From d8c19ac0f8759358a6d206a15262660b164a6adf Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Thu, 9 Jul 2020 14:35:34 +0200 Subject: [PATCH] user set bitcoin unit support --- drongo | 2 +- .../sparrowwallet/sparrow/AppController.java | 20 +++++++ .../sparrow/control/AddressTreeTable.java | 5 +- .../sparrow/control/CoinAxisFormatter.java | 31 ++++++++++ .../sparrow/control/CoinCell.java | 36 ++++++----- .../sparrow/control/CoinLabel.java | 12 +++- ...nFormatter.java => CoinTextFormatter.java} | 6 +- .../sparrow/control/CoinTreeTable.java | 36 +++++++++++ .../control/TransactionsTreeTable.java | 5 +- .../sparrow/control/UtxosChart.java | 29 +++++++-- .../sparrow/control/UtxosTreeTable.java | 5 +- .../event/BitcoinUnitChangedEvent.java | 15 +++++ .../com/sparrowwallet/sparrow/io/Config.java | 11 ++++ .../sparrow/wallet/AddressesController.java | 7 +++ .../sparrow/wallet/SendController.java | 60 ++++++++++++++++--- .../wallet/TransactionsController.java | 10 ++-- .../sparrow/wallet/UtxosController.java | 7 +++ .../wallet/WalletTransactionsEntry.java | 4 ++ .../com/sparrowwallet/sparrow/app.fxml | 23 +++++++ 19 files changed, 283 insertions(+), 41 deletions(-) create mode 100644 src/main/java/com/sparrowwallet/sparrow/control/CoinAxisFormatter.java rename src/main/java/com/sparrowwallet/sparrow/control/{CoinFormatter.java => CoinTextFormatter.java} (94%) create mode 100644 src/main/java/com/sparrowwallet/sparrow/control/CoinTreeTable.java create mode 100644 src/main/java/com/sparrowwallet/sparrow/event/BitcoinUnitChangedEvent.java diff --git a/drongo b/drongo index 4e7f0611..49a4b548 160000 --- a/drongo +++ b/drongo @@ -1 +1 @@ -Subproject commit 4e7f0611c4bd15ae983bd06feeb80ad69eedb853 +Subproject commit 49a4b548b4b93aa9b765b0b6f9520d0314b1395f diff --git a/src/main/java/com/sparrowwallet/sparrow/AppController.java b/src/main/java/com/sparrowwallet/sparrow/AppController.java index 7b26b63b..6a29fbbe 100644 --- a/src/main/java/com/sparrowwallet/sparrow/AppController.java +++ b/src/main/java/com/sparrowwallet/sparrow/AppController.java @@ -3,6 +3,7 @@ package com.sparrowwallet.sparrow; import com.google.common.base.Charsets; import com.google.common.eventbus.Subscribe; import com.google.common.io.ByteSource; +import com.sparrowwallet.drongo.BitcoinUnit; import com.sparrowwallet.drongo.SecureString; import com.sparrowwallet.drongo.Utils; import com.sparrowwallet.drongo.crypto.InvalidPasswordException; @@ -64,6 +65,9 @@ public class AppController implements Initializable { @FXML private MenuItem openTransactionIdItem; + @FXML + private ToggleGroup bitcoinUnit; + @FXML private CheckMenuItem showTxHex; @@ -146,6 +150,15 @@ public class AppController implements Initializable { } }); + BitcoinUnit unit = Config.get().getBitcoinUnit(); + if(unit == null) { + unit = BitcoinUnit.AUTO; + Config.get().setBitcoinUnit(unit); + } + final BitcoinUnit selectedUnit = unit; + Optional selectedToggle = bitcoinUnit.getToggles().stream().filter(toggle -> selectedUnit.equals(toggle.getUserData())).findFirst(); + selectedToggle.ifPresent(toggle -> bitcoinUnit.selectToggle(toggle)); + showTxHex.setSelected(true); showTxHexProperty = true; exportWallet.setDisable(true); @@ -374,6 +387,13 @@ public class AppController implements Initializable { showTxHexProperty = item.isSelected(); } + public void setBitcoinUnit(ActionEvent event) { + MenuItem item = (MenuItem)event.getSource(); + BitcoinUnit unit = (BitcoinUnit)item.getUserData(); + Config.get().setBitcoinUnit(unit); + EventManager.get().post(new BitcoinUnitChangedEvent(unit)); + } + public void newWallet(ActionEvent event) { WalletNameDialog dlg = new WalletNameDialog(); Optional walletName = dlg.showAndWait(); diff --git a/src/main/java/com/sparrowwallet/sparrow/control/AddressTreeTable.java b/src/main/java/com/sparrowwallet/sparrow/control/AddressTreeTable.java index a8c540a0..7774461c 100644 --- a/src/main/java/com/sparrowwallet/sparrow/control/AddressTreeTable.java +++ b/src/main/java/com/sparrowwallet/sparrow/control/AddressTreeTable.java @@ -15,9 +15,10 @@ import javafx.scene.text.Font; import java.util.List; import java.util.Optional; -public class AddressTreeTable extends TreeTableView { +public class AddressTreeTable extends CoinTreeTable { public void initialize(NodeEntry rootEntry) { getStyleClass().add("address-treetable"); + setBitcoinUnit(rootEntry.getWallet()); String address = rootEntry.getAddress().toString(); updateAll(rootEntry); @@ -80,6 +81,8 @@ public class AddressTreeTable extends TreeTableView { } public void updateAll(NodeEntry rootEntry) { + setBitcoinUnit(rootEntry.getWallet()); + RecursiveTreeItem rootItem = new RecursiveTreeItem<>(rootEntry, Entry::getChildren); setRoot(rootItem); rootItem.setExpanded(true); diff --git a/src/main/java/com/sparrowwallet/sparrow/control/CoinAxisFormatter.java b/src/main/java/com/sparrowwallet/sparrow/control/CoinAxisFormatter.java new file mode 100644 index 00000000..e2473c88 --- /dev/null +++ b/src/main/java/com/sparrowwallet/sparrow/control/CoinAxisFormatter.java @@ -0,0 +1,31 @@ +package com.sparrowwallet.sparrow.control; + +import com.sparrowwallet.drongo.BitcoinUnit; +import javafx.scene.chart.NumberAxis; +import javafx.util.StringConverter; + +import java.text.ParseException; + +final class CoinAxisFormatter extends StringConverter { + private final BitcoinUnit bitcoinUnit; + + public CoinAxisFormatter(NumberAxis axis, BitcoinUnit unit) { + this.bitcoinUnit = unit; + } + + @Override + public String toString(Number object) { + Double value = bitcoinUnit.getValue(object.longValue()); + return CoinTextFormatter.COIN_FORMAT.format(value); + } + + @Override + public Number fromString(String string) { + try { + Number number = CoinTextFormatter.COIN_FORMAT.parse(string); + return bitcoinUnit.getSatsValue(number.doubleValue()); + } catch (ParseException e) { + throw new RuntimeException(e); + } + } +} diff --git a/src/main/java/com/sparrowwallet/sparrow/control/CoinCell.java b/src/main/java/com/sparrowwallet/sparrow/control/CoinCell.java index 5850c11b..120ee953 100644 --- a/src/main/java/com/sparrowwallet/sparrow/control/CoinCell.java +++ b/src/main/java/com/sparrowwallet/sparrow/control/CoinCell.java @@ -1,5 +1,6 @@ package com.sparrowwallet.sparrow.control; +import com.sparrowwallet.drongo.BitcoinUnit; import com.sparrowwallet.drongo.protocol.Transaction; import com.sparrowwallet.sparrow.wallet.Entry; import com.sparrowwallet.sparrow.wallet.HashIndexEntry; @@ -13,8 +14,11 @@ import javafx.scene.layout.Region; import java.util.Locale; class CoinCell extends TreeTableCell { + private final Tooltip tooltip; + public CoinCell() { super(); + tooltip = new Tooltip(); getStyleClass().add("coin-cell"); } @@ -25,23 +29,33 @@ class CoinCell extends TreeTableCell { if(empty || amount == null) { setText(null); setGraphic(null); + setTooltip(null); } else { Entry entry = getTreeTableView().getTreeItem(getIndex()).getValue(); EntryCell.applyRowStyles(this, entry); + CoinTreeTable coinTreeTable = (CoinTreeTable)getTreeTableView(); + BitcoinUnit unit = coinTreeTable.getBitcoinUnit(); + String satsValue = String.format(Locale.ENGLISH, "%,d", amount.longValue()); - final String btcValue = CoinLabel.getBTCFormat().format(amount.doubleValue() / Transaction.SATOSHIS_PER_BITCOIN) + " BTC"; + final String btcValue = CoinLabel.getBTCFormat().format(amount.doubleValue() / Transaction.SATOSHIS_PER_BITCOIN); + + if(unit.equals(BitcoinUnit.BTC)) { + tooltip.setText(satsValue + " " + BitcoinUnit.SATOSHIS.getLabel()); + setText(btcValue); + } else { + tooltip.setText(btcValue + " " + BitcoinUnit.BTC.getLabel()); + setText(satsValue); + } + setTooltip(tooltip); + String tooltipValue = tooltip.getText(); if(entry instanceof TransactionEntry) { TransactionEntry transactionEntry = (TransactionEntry)entry; - Tooltip tooltip = new Tooltip(); - tooltip.setText(btcValue + " (" + transactionEntry.getConfirmationsDescription() + ")"); - setTooltip(tooltip); + tooltip.setText(tooltipValue + " (" + transactionEntry.getConfirmationsDescription() + ")"); transactionEntry.confirmationsProperty().addListener((observable, oldValue, newValue) -> { - Tooltip newTooltip = new Tooltip(); - newTooltip.setText(btcValue + " (" + transactionEntry.getConfirmationsDescription() + ")"); - setTooltip(newTooltip); + tooltip.setText(tooltipValue + " (" + transactionEntry.getConfirmationsDescription() + ")"); }); if(transactionEntry.isConfirming()) { @@ -66,14 +80,6 @@ class CoinCell extends TreeTableCell { } else { setGraphic(null); } - - if(getTooltip() == null) { - Tooltip tooltip = new Tooltip(); - tooltip.setText(btcValue); - setTooltip(tooltip); - } - - setText(satsValue); } } } diff --git a/src/main/java/com/sparrowwallet/sparrow/control/CoinLabel.java b/src/main/java/com/sparrowwallet/sparrow/control/CoinLabel.java index 0170b1d8..304105ed 100644 --- a/src/main/java/com/sparrowwallet/sparrow/control/CoinLabel.java +++ b/src/main/java/com/sparrowwallet/sparrow/control/CoinLabel.java @@ -1,6 +1,8 @@ package com.sparrowwallet.sparrow.control; +import com.sparrowwallet.drongo.BitcoinUnit; import com.sparrowwallet.drongo.protocol.Transaction; +import com.sparrowwallet.sparrow.io.Config; import javafx.beans.property.LongProperty; import javafx.beans.property.SimpleLongProperty; import javafx.scene.control.ContextMenu; @@ -14,8 +16,6 @@ import java.text.DecimalFormatSymbols; import java.util.Locale; public class CoinLabel extends CopyableLabel { - public static final int MAX_SATS_SHOWN = 1000000; - public static final DecimalFormat BTC_FORMAT = new DecimalFormat("0", DecimalFormatSymbols.getInstance(Locale.ENGLISH)); private final LongProperty value = new SimpleLongProperty(-1); @@ -52,7 +52,13 @@ public class CoinLabel extends CopyableLabel { String satsValue = String.format(Locale.ENGLISH, "%,d",value) + " sats"; String btcValue = BTC_FORMAT.format(value.doubleValue() / Transaction.SATOSHIS_PER_BITCOIN) + " BTC"; - if(value > MAX_SATS_SHOWN) { + + BitcoinUnit unit = Config.get().getBitcoinUnit(); + if(unit == null || unit.equals(BitcoinUnit.AUTO)) { + unit = (value >= BitcoinUnit.getAutoThreshold() ? BitcoinUnit.BTC : BitcoinUnit.SATOSHIS); + } + + if(unit.equals(BitcoinUnit.BTC)) { tooltip.setText(satsValue); setText(btcValue); } else { diff --git a/src/main/java/com/sparrowwallet/sparrow/control/CoinFormatter.java b/src/main/java/com/sparrowwallet/sparrow/control/CoinTextFormatter.java similarity index 94% rename from src/main/java/com/sparrowwallet/sparrow/control/CoinFormatter.java rename to src/main/java/com/sparrowwallet/sparrow/control/CoinTextFormatter.java index 46822953..9fbc6216 100644 --- a/src/main/java/com/sparrowwallet/sparrow/control/CoinFormatter.java +++ b/src/main/java/com/sparrowwallet/sparrow/control/CoinTextFormatter.java @@ -8,11 +8,11 @@ import java.text.ParseException; import java.util.function.UnaryOperator; import java.util.regex.Pattern; -public class CoinFormatter extends TextFormatter { +public class CoinTextFormatter extends TextFormatter { private static final Pattern COIN_VALIDATION = Pattern.compile("[\\d,]*(\\.\\d{0,8})?"); - private static final DecimalFormat COIN_FORMAT = new DecimalFormat("###,###.########"); + public static final DecimalFormat COIN_FORMAT = new DecimalFormat("###,###.########"); - public CoinFormatter() { + public CoinTextFormatter() { super(new CoinFilter()); } diff --git a/src/main/java/com/sparrowwallet/sparrow/control/CoinTreeTable.java b/src/main/java/com/sparrowwallet/sparrow/control/CoinTreeTable.java new file mode 100644 index 00000000..7afb2570 --- /dev/null +++ b/src/main/java/com/sparrowwallet/sparrow/control/CoinTreeTable.java @@ -0,0 +1,36 @@ +package com.sparrowwallet.sparrow.control; + +import com.sparrowwallet.drongo.BitcoinUnit; +import com.sparrowwallet.drongo.wallet.Wallet; +import com.sparrowwallet.sparrow.io.Config; +import com.sparrowwallet.sparrow.wallet.Entry; +import javafx.scene.control.TreeTableView; + +public class CoinTreeTable extends TreeTableView { + private BitcoinUnit bitcoinUnit; + + public BitcoinUnit getBitcoinUnit() { + return bitcoinUnit; + } + + public void setBitcoinUnit(BitcoinUnit bitcoinUnit) { + this.bitcoinUnit = bitcoinUnit; + } + + public void setBitcoinUnit(Wallet wallet) { + setBitcoinUnit(wallet, Config.get().getBitcoinUnit()); + } + + public void setBitcoinUnit(Wallet wallet, BitcoinUnit unit) { + if(unit == null || unit.equals(BitcoinUnit.AUTO)) { + unit = wallet.getAutoUnit(); + } + + boolean changed = (bitcoinUnit != unit); + this.bitcoinUnit = unit; + + if(changed && !getChildren().isEmpty()) { + refresh(); + } + } +} diff --git a/src/main/java/com/sparrowwallet/sparrow/control/TransactionsTreeTable.java b/src/main/java/com/sparrowwallet/sparrow/control/TransactionsTreeTable.java index 937258cf..81b6f693 100644 --- a/src/main/java/com/sparrowwallet/sparrow/control/TransactionsTreeTable.java +++ b/src/main/java/com/sparrowwallet/sparrow/control/TransactionsTreeTable.java @@ -11,9 +11,10 @@ import javafx.scene.control.TreeTableView; import java.util.List; -public class TransactionsTreeTable extends TreeTableView { +public class TransactionsTreeTable extends CoinTreeTable { public void initialize(WalletTransactionsEntry rootEntry) { getStyleClass().add("transactions-treetable"); + setBitcoinUnit(rootEntry.getWallet()); updateAll(rootEntry); setShowRoot(false); @@ -58,6 +59,8 @@ public class TransactionsTreeTable extends TreeTableView { } public void updateAll(WalletTransactionsEntry rootEntry) { + setBitcoinUnit(rootEntry.getWallet()); + RecursiveTreeItem rootItem = new RecursiveTreeItem<>(rootEntry, Entry::getChildren); setRoot(rootItem); rootItem.setExpanded(true); diff --git a/src/main/java/com/sparrowwallet/sparrow/control/UtxosChart.java b/src/main/java/com/sparrowwallet/sparrow/control/UtxosChart.java index a1e30e06..1c545b3b 100644 --- a/src/main/java/com/sparrowwallet/sparrow/control/UtxosChart.java +++ b/src/main/java/com/sparrowwallet/sparrow/control/UtxosChart.java @@ -1,13 +1,14 @@ package com.sparrowwallet.sparrow.control; +import com.sparrowwallet.drongo.BitcoinUnit; +import com.sparrowwallet.drongo.wallet.Wallet; +import com.sparrowwallet.sparrow.io.Config; import com.sparrowwallet.sparrow.wallet.Entry; import com.sparrowwallet.sparrow.wallet.UtxoEntry; import com.sparrowwallet.sparrow.wallet.WalletUtxosEntry; import javafx.beans.NamedArg; import javafx.scene.Node; -import javafx.scene.chart.Axis; -import javafx.scene.chart.BarChart; -import javafx.scene.chart.XYChart; +import javafx.scene.chart.*; import java.util.List; import java.util.Set; @@ -30,11 +31,14 @@ public class UtxosChart extends BarChart { utxoSeries = new XYChart.Series<>(); getData().add(utxoSeries); update(walletUtxosEntry); + + BitcoinUnit unit = Config.get().getBitcoinUnit(); + setBitcoinUnit(walletUtxosEntry.getWallet(), unit); } public void update(WalletUtxosEntry walletUtxosEntry) { List> utxoDataList = walletUtxosEntry.getChildren().stream() - .map(entry -> new XYChart.Data<>(entry.getLabel() != null && !entry.getLabel().isEmpty() ? entry.getLabel() : ((UtxoEntry)entry).getDescription(), (Number)entry.getValue(), entry)) + .map(entry -> new XYChart.Data<>(getCategoryName(entry), (Number)entry.getValue(), entry)) .sorted((o1, o2) -> (int) (o2.getYValue().longValue() - o1.getYValue().longValue())) .collect(Collectors.toList()); @@ -66,6 +70,14 @@ public class UtxosChart extends BarChart { } } + private String getCategoryName(Entry entry) { + if(entry.getLabel() != null && !entry.getLabel().isEmpty()) { + return entry.getLabel().length() > 15 ? entry.getLabel().substring(0, 15) + "..." : entry.getLabel(); + } + + return ((UtxoEntry)entry).getDescription(); + } + public void select(List entries) { Set selectedBars = lookupAll(".chart-bar.selected"); for(Node selectedBar : selectedBars) { @@ -86,4 +98,13 @@ public class UtxosChart extends BarChart { this.selectedEntries = entries; } + + public void setBitcoinUnit(Wallet wallet, BitcoinUnit unit) { + if(unit == null || unit.equals(BitcoinUnit.AUTO)) { + unit = wallet.getAutoUnit(); + } + + NumberAxis yaxis = (NumberAxis)getYAxis(); + yaxis.setTickLabelFormatter(new CoinAxisFormatter(yaxis, unit)); + } } diff --git a/src/main/java/com/sparrowwallet/sparrow/control/UtxosTreeTable.java b/src/main/java/com/sparrowwallet/sparrow/control/UtxosTreeTable.java index c4490da1..375ef5ca 100644 --- a/src/main/java/com/sparrowwallet/sparrow/control/UtxosTreeTable.java +++ b/src/main/java/com/sparrowwallet/sparrow/control/UtxosTreeTable.java @@ -10,9 +10,10 @@ import javafx.scene.control.TreeTableView; import java.util.List; -public class UtxosTreeTable extends TreeTableView { +public class UtxosTreeTable extends CoinTreeTable { public void initialize(WalletUtxosEntry rootEntry) { getStyleClass().add("utxos-treetable"); + setBitcoinUnit(rootEntry.getWallet()); updateAll(rootEntry); setShowRoot(false); @@ -78,6 +79,8 @@ public class UtxosTreeTable extends TreeTableView { } public void updateAll(WalletUtxosEntry rootEntry) { + setBitcoinUnit(rootEntry.getWallet()); + RecursiveTreeItem rootItem = new RecursiveTreeItem<>(rootEntry, Entry::getChildren); setRoot(rootItem); rootItem.setExpanded(true); diff --git a/src/main/java/com/sparrowwallet/sparrow/event/BitcoinUnitChangedEvent.java b/src/main/java/com/sparrowwallet/sparrow/event/BitcoinUnitChangedEvent.java new file mode 100644 index 00000000..3f78d7d3 --- /dev/null +++ b/src/main/java/com/sparrowwallet/sparrow/event/BitcoinUnitChangedEvent.java @@ -0,0 +1,15 @@ +package com.sparrowwallet.sparrow.event; + +import com.sparrowwallet.drongo.BitcoinUnit; + +public class BitcoinUnitChangedEvent { + private final BitcoinUnit bitcoinUnit; + + public BitcoinUnitChangedEvent(BitcoinUnit bitcoinUnit) { + this.bitcoinUnit = bitcoinUnit; + } + + public BitcoinUnit getBitcoinUnit() { + return bitcoinUnit; + } +} diff --git a/src/main/java/com/sparrowwallet/sparrow/io/Config.java b/src/main/java/com/sparrowwallet/sparrow/io/Config.java index 6848295f..dd0e599c 100644 --- a/src/main/java/com/sparrowwallet/sparrow/io/Config.java +++ b/src/main/java/com/sparrowwallet/sparrow/io/Config.java @@ -1,6 +1,7 @@ package com.sparrowwallet.sparrow.io; import com.google.gson.*; +import com.sparrowwallet.drongo.BitcoinUnit; import com.sparrowwallet.sparrow.Mode; import java.io.*; @@ -10,6 +11,7 @@ public class Config { public static final String CONFIG_FILENAME = ".config"; private Mode mode; + private BitcoinUnit bitcoinUnit; private Integer keyDerivationPeriod; private File hwi; private String electrumServer; @@ -67,6 +69,15 @@ public class Config { flush(); } + public BitcoinUnit getBitcoinUnit() { + return bitcoinUnit; + } + + public void setBitcoinUnit(BitcoinUnit bitcoinUnit) { + this.bitcoinUnit = bitcoinUnit; + flush(); + } + public Integer getKeyDerivationPeriod() { return keyDerivationPeriod; } diff --git a/src/main/java/com/sparrowwallet/sparrow/wallet/AddressesController.java b/src/main/java/com/sparrowwallet/sparrow/wallet/AddressesController.java index 1f0b560a..35e9271d 100644 --- a/src/main/java/com/sparrowwallet/sparrow/wallet/AddressesController.java +++ b/src/main/java/com/sparrowwallet/sparrow/wallet/AddressesController.java @@ -5,6 +5,7 @@ import com.sparrowwallet.drongo.KeyPurpose; import com.sparrowwallet.drongo.wallet.WalletNode; import com.sparrowwallet.sparrow.EventManager; import com.sparrowwallet.sparrow.control.AddressTreeTable; +import com.sparrowwallet.sparrow.event.BitcoinUnitChangedEvent; import com.sparrowwallet.sparrow.event.WalletEntryLabelChangedEvent; import com.sparrowwallet.sparrow.event.WalletHistoryChangedEvent; import com.sparrowwallet.sparrow.event.WalletNodesChangedEvent; @@ -63,4 +64,10 @@ public class AddressesController extends WalletFormController implements Initial changeTable.updateLabel(event.getEntry()); } } + + @Subscribe + public void bitcoinUnitChanged(BitcoinUnitChangedEvent event) { + receiveTable.setBitcoinUnit(getWalletForm().getWallet(), event.getBitcoinUnit()); + changeTable.setBitcoinUnit(getWalletForm().getWallet(), event.getBitcoinUnit()); + } } diff --git a/src/main/java/com/sparrowwallet/sparrow/wallet/SendController.java b/src/main/java/com/sparrowwallet/sparrow/wallet/SendController.java index aaff4cc8..5dc49a08 100644 --- a/src/main/java/com/sparrowwallet/sparrow/wallet/SendController.java +++ b/src/main/java/com/sparrowwallet/sparrow/wallet/SendController.java @@ -8,8 +8,8 @@ import com.sparrowwallet.drongo.wallet.*; import com.sparrowwallet.sparrow.AppController; import com.sparrowwallet.sparrow.EventManager; import com.sparrowwallet.sparrow.control.*; -import com.sparrowwallet.sparrow.event.FeeRatesUpdatedEvent; -import com.sparrowwallet.sparrow.event.SpendUtxoEvent; +import com.sparrowwallet.sparrow.event.*; +import com.sparrowwallet.sparrow.io.Config; import javafx.beans.property.BooleanProperty; import javafx.beans.property.ObjectProperty; import javafx.beans.property.SimpleBooleanProperty; @@ -29,6 +29,7 @@ import org.controlsfx.validation.decoration.StyleClassValidationDecoration; import java.net.URL; import java.text.DecimalFormat; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.ResourceBundle; @@ -141,10 +142,15 @@ public class SendController extends WalletFormController implements Initializabl updateTransaction(); }); - amount.setTextFormatter(new CoinFormatter()); + amount.setTextFormatter(new CoinTextFormatter()); amount.textProperty().addListener(amountListener); - amountUnit.getSelectionModel().select(1); + BitcoinUnit unit = Config.get().getBitcoinUnit(); + if(unit == null || unit.equals(BitcoinUnit.AUTO)) { + unit = getWalletForm().getWallet().getAutoUnit(); + } + + amountUnit.getSelectionModel().select(BitcoinUnit.BTC.equals(unit) ? 0 : 1); amountUnit.valueProperty().addListener((observable, oldValue, newValue) -> { Long value = getRecipientValueSats(oldValue); if(value != null) { @@ -197,10 +203,10 @@ public class SendController extends WalletFormController implements Initializabl setTargetBlocks(5); - fee.setTextFormatter(new CoinFormatter()); + fee.setTextFormatter(new CoinTextFormatter()); fee.textProperty().addListener(feeListener); - feeAmountUnit.getSelectionModel().select(1); + feeAmountUnit.getSelectionModel().select(BitcoinUnit.BTC.equals(unit) ? 0 : 1); feeAmountUnit.valueProperty().addListener((observable, oldValue, newValue) -> { Long value = getFeeValueSats(oldValue); if(value != null) { @@ -305,7 +311,12 @@ public class SendController extends WalletFormController implements Initializabl return List.of(utxoSelectorProperty.get()); } - UtxoSelector priorityUtxoSelector = new PriorityUtxoSelector(AppController.getCurrentBlockHeight()); + Integer blockHeight = AppController.getCurrentBlockHeight(); + if(blockHeight == null) { + blockHeight = getWalletForm().getWallet().getStoredBlockHeight(); + } + + UtxoSelector priorityUtxoSelector = new PriorityUtxoSelector(blockHeight); return List.of(priorityUtxoSelector); } @@ -395,7 +406,9 @@ public class SendController extends WalletFormController implements Initializabl private Map getTargetBlocksFeeRates() { Map retrievedFeeRates = AppController.getTargetBlockFeeRates(); if(retrievedFeeRates == null) { - retrievedFeeRates = TARGET_BLOCKS_RANGE.stream().collect(Collectors.toMap(java.util.function.Function.identity(), v -> FALLBACK_FEE_RATE)); + retrievedFeeRates = TARGET_BLOCKS_RANGE.stream().collect(Collectors.toMap(java.util.function.Function.identity(), v -> FALLBACK_FEE_RATE, + (u, v) -> { throw new IllegalStateException("Duplicate target blocks"); }, + LinkedHashMap::new)); } return retrievedFeeRates; @@ -449,6 +462,27 @@ public class SendController extends WalletFormController implements Initializabl } + @Subscribe + public void walletNodesChanged(WalletNodesChangedEvent event) { + if(event.getWallet().equals(walletForm.getWallet())) { + clear(null); + } + } + + @Subscribe + public void walletHistoryChanged(WalletHistoryChangedEvent event) { + if(event.getWallet().equals(walletForm.getWallet())) { + updateTransaction(); + } + } + + @Subscribe + public void walletEntryLabelChanged(WalletEntryLabelChangedEvent event) { + if(event.getWallet().equals(walletForm.getWallet())) { + updateTransaction(); + } + } + @Subscribe public void feeRatesUpdated(FeeRatesUpdatedEvent event) { feeRatesChart.update(event.getTargetBlockFeeRates()); @@ -464,4 +498,14 @@ public class SendController extends WalletFormController implements Initializabl updateTransaction(true); } } + + @Subscribe + public void bitcoinUnitChanged(BitcoinUnitChangedEvent event) { + BitcoinUnit unit = event.getBitcoinUnit(); + if(unit == null || unit.equals(BitcoinUnit.AUTO)) { + unit = getWalletForm().getWallet().getAutoUnit(); + } + amountUnit.getSelectionModel().select(BitcoinUnit.BTC.equals(unit) ? 0 : 1); + feeAmountUnit.getSelectionModel().select(BitcoinUnit.BTC.equals(unit) ? 0 : 1); + } } diff --git a/src/main/java/com/sparrowwallet/sparrow/wallet/TransactionsController.java b/src/main/java/com/sparrowwallet/sparrow/wallet/TransactionsController.java index d7623a22..f0959d22 100644 --- a/src/main/java/com/sparrowwallet/sparrow/wallet/TransactionsController.java +++ b/src/main/java/com/sparrowwallet/sparrow/wallet/TransactionsController.java @@ -3,10 +3,7 @@ package com.sparrowwallet.sparrow.wallet; import com.google.common.eventbus.Subscribe; import com.sparrowwallet.sparrow.EventManager; import com.sparrowwallet.sparrow.control.TransactionsTreeTable; -import com.sparrowwallet.sparrow.event.WalletBlockHeightChangedEvent; -import com.sparrowwallet.sparrow.event.WalletEntryLabelChangedEvent; -import com.sparrowwallet.sparrow.event.WalletHistoryChangedEvent; -import com.sparrowwallet.sparrow.event.WalletNodesChangedEvent; +import com.sparrowwallet.sparrow.event.*; import javafx.fxml.FXML; import javafx.fxml.Initializable; import javafx.scene.input.MouseEvent; @@ -50,6 +47,11 @@ public class TransactionsController extends WalletFormController implements Init } } + @Subscribe + public void bitcoinUnitChanged(BitcoinUnitChangedEvent event) { + transactionsTable.setBitcoinUnit(getWalletForm().getWallet(), event.getBitcoinUnit()); + } + //TODO: Remove public void advanceBlock(MouseEvent event) { Integer currentBlock = getWalletForm().getWallet().getStoredBlockHeight(); diff --git a/src/main/java/com/sparrowwallet/sparrow/wallet/UtxosController.java b/src/main/java/com/sparrowwallet/sparrow/wallet/UtxosController.java index 1f6fe992..8f7943ba 100644 --- a/src/main/java/com/sparrowwallet/sparrow/wallet/UtxosController.java +++ b/src/main/java/com/sparrowwallet/sparrow/wallet/UtxosController.java @@ -4,6 +4,7 @@ import com.google.common.eventbus.Subscribe; import com.sparrowwallet.sparrow.EventManager; import com.sparrowwallet.sparrow.control.UtxosChart; import com.sparrowwallet.sparrow.control.UtxosTreeTable; +import com.sparrowwallet.sparrow.event.BitcoinUnitChangedEvent; import com.sparrowwallet.sparrow.event.WalletEntryLabelChangedEvent; import com.sparrowwallet.sparrow.event.WalletHistoryChangedEvent; import com.sparrowwallet.sparrow.event.WalletNodesChangedEvent; @@ -63,4 +64,10 @@ public class UtxosController extends WalletFormController implements Initializab utxosChart.update(getWalletForm().getWalletUtxosEntry()); } } + + @Subscribe + public void bitcoinUnitChanged(BitcoinUnitChangedEvent event) { + utxosTable.setBitcoinUnit(getWalletForm().getWallet(), event.getBitcoinUnit()); + utxosChart.setBitcoinUnit(getWalletForm().getWallet(), event.getBitcoinUnit()); + } } diff --git a/src/main/java/com/sparrowwallet/sparrow/wallet/WalletTransactionsEntry.java b/src/main/java/com/sparrowwallet/sparrow/wallet/WalletTransactionsEntry.java index b85523ff..896ac409 100644 --- a/src/main/java/com/sparrowwallet/sparrow/wallet/WalletTransactionsEntry.java +++ b/src/main/java/com/sparrowwallet/sparrow/wallet/WalletTransactionsEntry.java @@ -20,6 +20,10 @@ public class WalletTransactionsEntry extends Entry { calculateBalances(); } + public Wallet getWallet() { + return wallet; + } + @Override public Long getValue() { return getBalance(); diff --git a/src/main/resources/com/sparrowwallet/sparrow/app.fxml b/src/main/resources/com/sparrowwallet/sparrow/app.fxml index bc580d43..5fb01cdd 100644 --- a/src/main/resources/com/sparrowwallet/sparrow/app.fxml +++ b/src/main/resources/com/sparrowwallet/sparrow/app.fxml @@ -6,6 +6,7 @@ + @@ -34,8 +35,30 @@ + + + + + + + + + + + + + + + + + + + + + +