diff --git a/drongo b/drongo index e8bb733e..0fbce035 160000 --- a/drongo +++ b/drongo @@ -1 +1 @@ -Subproject commit e8bb733ea8a6e476982e5ea78c288105d0bd8644 +Subproject commit 0fbce035a3083f1cd5dc9f168b0cd4365a75ce40 diff --git a/src/main/java/com/sparrowwallet/sparrow/control/CoinLabel.java b/src/main/java/com/sparrowwallet/sparrow/control/CoinLabel.java index df2f0fae..8ce5dad4 100644 --- a/src/main/java/com/sparrowwallet/sparrow/control/CoinLabel.java +++ b/src/main/java/com/sparrowwallet/sparrow/control/CoinLabel.java @@ -58,7 +58,7 @@ public class CoinLabel extends CopyableLabel { setTooltip(tooltip); setContextMenu(contextMenu); - String satsValue = String.format(Locale.ENGLISH, "%,d",value) + " sats"; + String satsValue = String.format(Locale.ENGLISH, "%,d", value) + " sats"; String btcValue = BTC_FORMAT.format(value.doubleValue() / Transaction.SATOSHIS_PER_BITCOIN) + " BTC"; BitcoinUnit unit = bitcoinUnit; diff --git a/src/main/java/com/sparrowwallet/sparrow/control/DateCell.java b/src/main/java/com/sparrowwallet/sparrow/control/DateCell.java index 10776a32..817abcf7 100644 --- a/src/main/java/com/sparrowwallet/sparrow/control/DateCell.java +++ b/src/main/java/com/sparrowwallet/sparrow/control/DateCell.java @@ -34,7 +34,7 @@ public class DateCell extends TreeTableCell { if(entry instanceof UtxoEntry) { UtxoEntry utxoEntry = (UtxoEntry)entry; if(utxoEntry.getHashIndex().getHeight() <= 0) { - setText("Unconfirmed"); + setText("Unconfirmed " + (utxoEntry.isSpendable() ? "(Spendable)" : "(Not yet spendable)")); } else { String date = DATE_FORMAT.format(utxoEntry.getHashIndex().getDate()); setText(date); diff --git a/src/main/java/com/sparrowwallet/sparrow/control/EntryCell.java b/src/main/java/com/sparrowwallet/sparrow/control/EntryCell.java index c96e5b5c..e6f80e6c 100644 --- a/src/main/java/com/sparrowwallet/sparrow/control/EntryCell.java +++ b/src/main/java/com/sparrowwallet/sparrow/control/EntryCell.java @@ -225,9 +225,11 @@ class EntryCell extends TreeTableCell { public static void applyRowStyles(TreeTableCell cell, Entry entry) { cell.getStyleClass().remove("transaction-row"); cell.getStyleClass().remove("node-row"); + cell.getStyleClass().remove("utxo-row"); cell.getStyleClass().remove("address-cell"); cell.getStyleClass().remove("hashindex-row"); cell.getStyleClass().remove("spent"); + cell.getStyleClass().remove("unspendable"); if(entry != null) { if(entry instanceof TransactionEntry) { @@ -245,6 +247,10 @@ class EntryCell extends TreeTableCell { cell.getStyleClass().add("node-row"); } else if(entry instanceof UtxoEntry) { cell.getStyleClass().add("utxo-row"); + UtxoEntry utxoEntry = (UtxoEntry)entry; + if(!utxoEntry.isSpendable()) { + cell.getStyleClass().add("unspendable"); + } } else if(entry instanceof HashIndexEntry) { cell.getStyleClass().add("hashindex-row"); HashIndexEntry hashIndexEntry = (HashIndexEntry)entry; diff --git a/src/main/java/com/sparrowwallet/sparrow/wallet/UtxosController.java b/src/main/java/com/sparrowwallet/sparrow/wallet/UtxosController.java index dbd4d6ef..dbac9c45 100644 --- a/src/main/java/com/sparrowwallet/sparrow/wallet/UtxosController.java +++ b/src/main/java/com/sparrowwallet/sparrow/wallet/UtxosController.java @@ -1,19 +1,24 @@ package com.sparrowwallet.sparrow.wallet; import com.google.common.eventbus.Subscribe; +import com.sparrowwallet.drongo.BitcoinUnit; +import com.sparrowwallet.drongo.protocol.Transaction; import com.sparrowwallet.sparrow.EventManager; +import com.sparrowwallet.sparrow.control.CoinLabel; 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; +import com.sparrowwallet.sparrow.event.*; +import com.sparrowwallet.sparrow.io.Config; +import javafx.application.Platform; import javafx.collections.ListChangeListener; +import javafx.event.ActionEvent; import javafx.fxml.FXML; import javafx.fxml.Initializable; +import javafx.scene.control.Button; import java.net.URL; import java.util.List; +import java.util.Locale; import java.util.ResourceBundle; import java.util.stream.Collectors; @@ -22,6 +27,9 @@ public class UtxosController extends WalletFormController implements Initializab @FXML private UtxosTreeTable utxosTable; + @FXML + private Button sendSelected; + @FXML private UtxosChart utxosChart; @@ -34,13 +42,53 @@ public class UtxosController extends WalletFormController implements Initializab public void initializeView() { utxosTable.initialize(getWalletForm().getWalletUtxosEntry()); utxosChart.initialize(getWalletForm().getWalletUtxosEntry()); + sendSelected.setDisable(true); utxosTable.getSelectionModel().getSelectedIndices().addListener((ListChangeListener) c -> { List selectedEntries = utxosTable.getSelectionModel().getSelectedCells().stream().map(tp -> tp.getTreeItem().getValue()).collect(Collectors.toList()); utxosChart.select(selectedEntries); + updateSendSelected(Config.get().getBitcoinUnit()); }); } + private void updateSendSelected(BitcoinUnit unit) { + List selectedEntries = utxosTable.getSelectionModel().getSelectedCells().stream().map(tp -> tp.getTreeItem().getValue()) + .filter(entry -> ((HashIndexEntry)entry).isSpendable()) + .collect(Collectors.toList()); + + sendSelected.setDisable(selectedEntries.isEmpty()); + long selectedTotal = selectedEntries.stream().mapToLong(Entry::getValue).sum(); + if(selectedTotal > 0) { + if(unit == null || unit.equals(BitcoinUnit.AUTO)) { + unit = (selectedTotal >= BitcoinUnit.getAutoThreshold() ? BitcoinUnit.BTC : BitcoinUnit.SATOSHIS); + } + + if(unit.equals(BitcoinUnit.BTC)) { + sendSelected.setText("Send Selected (" + CoinLabel.getBTCFormat().format((double)selectedTotal / Transaction.SATOSHIS_PER_BITCOIN) + " BTC)"); + } else { + sendSelected.setText("Send Selected (" + String.format(Locale.ENGLISH, "%,d", selectedTotal) + " sats)"); + } + } else { + sendSelected.setText("Send Selected"); + } + } + + public void sendSelected(ActionEvent event) { + List utxoEntries = utxosTable.getSelectionModel().getSelectedCells().stream() + .map(tp -> tp.getTreeItem().getValue()) + .filter(e -> e instanceof HashIndexEntry) + .map(e -> (HashIndexEntry)e) + .filter(e -> e.getType().equals(HashIndexEntry.Type.OUTPUT) && e.isSpendable()) + .collect(Collectors.toList()); + + EventManager.get().post(new SendActionEvent(utxoEntries)); + Platform.runLater(() -> EventManager.get().post(new SpendUtxoEvent(utxoEntries))); + } + + public void clear(ActionEvent event) { + utxosTable.getSelectionModel().clearSelection(); + } + @Subscribe public void walletNodesChanged(WalletNodesChangedEvent event) { if(event.getWallet().equals(walletForm.getWallet())) { @@ -75,5 +123,6 @@ public class UtxosController extends WalletFormController implements Initializab public void bitcoinUnitChanged(BitcoinUnitChangedEvent event) { utxosTable.setBitcoinUnit(getWalletForm().getWallet(), event.getBitcoinUnit()); utxosChart.setBitcoinUnit(getWalletForm().getWallet(), event.getBitcoinUnit()); + updateSendSelected(event.getBitcoinUnit()); } } diff --git a/src/main/resources/com/sparrowwallet/sparrow/wallet/utxos.css b/src/main/resources/com/sparrowwallet/sparrow/wallet/utxos.css index 772919fa..5c2fa481 100644 --- a/src/main/resources/com/sparrowwallet/sparrow/wallet/utxos.css +++ b/src/main/resources/com/sparrowwallet/sparrow/wallet/utxos.css @@ -4,6 +4,10 @@ -fx-padding: 10 0 10 0; } +.utxos-buttons-box { + -fx-padding: 15 0 0 0; +} + .chart-bar { -fx-bar-fill: rgba(105, 108, 119, 0.6); } diff --git a/src/main/resources/com/sparrowwallet/sparrow/wallet/utxos.fxml b/src/main/resources/com/sparrowwallet/sparrow/wallet/utxos.fxml index bc1e7611..93016bef 100644 --- a/src/main/resources/com/sparrowwallet/sparrow/wallet/utxos.fxml +++ b/src/main/resources/com/sparrowwallet/sparrow/wallet/utxos.fxml @@ -12,36 +12,51 @@ + - + - - - - - - - - - - -
- -
-
- -
- - - - - - - - -
-
-
+
+ + + + + + + + + + + +
+ +
+ + + + + +
+ +
+ + + + + + + + +
+
+
+
+ diff --git a/src/main/resources/com/sparrowwallet/sparrow/wallet/wallet.css b/src/main/resources/com/sparrowwallet/sparrow/wallet/wallet.css index 90330e71..9c2eb30d 100644 --- a/src/main/resources/com/sparrowwallet/sparrow/wallet/wallet.css +++ b/src/main/resources/com/sparrowwallet/sparrow/wallet/wallet.css @@ -45,6 +45,18 @@ -fx-text-fill: #696c77; } +.utxo-row.unspendable { + -fx-text-fill: #a0a1a7; +} + +.tree-table-row-cell:selected .utxo-row.unspendable { + -fx-text-fill: #696c77; +} + +.tree-table-view:focused:row-selection .tree-table-row-cell:selected .utxo-row.unspendable { + -fx-text-fill: derive(white, -15%); +} + .tree-table-row-cell:selected .hashindex-row, .tree-table-row-cell:selected .transaction-row { -fx-text-fill: white; }