diff --git a/src/main/java/com/sparrowwallet/sparrow/control/TransactionDiagram.java b/src/main/java/com/sparrowwallet/sparrow/control/TransactionDiagram.java index 0ffbe0c4..46ffc331 100644 --- a/src/main/java/com/sparrowwallet/sparrow/control/TransactionDiagram.java +++ b/src/main/java/com/sparrowwallet/sparrow/control/TransactionDiagram.java @@ -431,6 +431,17 @@ public class TransactionDiagram extends GridPane { return consolidationGlyph; } + public static Glyph getTxoGlyph() { + return getChangeGlyph(); + } + + public static Glyph getPayjoinGlyph() { + Glyph payjoinGlyph = new Glyph(FontAwesome5.FONT_NAME, FontAwesome5.Glyph.RANDOM); + payjoinGlyph.getStyleClass().add("payjoin-icon"); + payjoinGlyph.setFontSize(12); + return payjoinGlyph; + } + public static Glyph getChangeGlyph() { Glyph changeGlyph = new Glyph(FontAwesome5.FONT_NAME, FontAwesome5.Glyph.COINS); changeGlyph.getStyleClass().add("change-icon"); diff --git a/src/main/java/com/sparrowwallet/sparrow/transaction/InputController.java b/src/main/java/com/sparrowwallet/sparrow/transaction/InputController.java index 2641af03..63b6270c 100644 --- a/src/main/java/com/sparrowwallet/sparrow/transaction/InputController.java +++ b/src/main/java/com/sparrowwallet/sparrow/transaction/InputController.java @@ -8,6 +8,7 @@ import com.sparrowwallet.drongo.protocol.*; import com.sparrowwallet.drongo.psbt.PSBTInput; import com.sparrowwallet.drongo.wallet.BlockTransaction; import com.sparrowwallet.drongo.wallet.Keystore; +import com.sparrowwallet.drongo.wallet.Wallet; import com.sparrowwallet.sparrow.EventManager; import com.sparrowwallet.sparrow.control.*; import com.sparrowwallet.sparrow.event.*; @@ -120,6 +121,11 @@ public class InputController extends TransactionFormController implements Initia TransactionInput txInput = inputForm.getTransactionInput(); PSBTInput psbtInput = inputForm.getPsbtInput(); + inputForm.signingWalletProperty().addListener((observable, oldValue, signingWallet) -> { + updateInputLegendFromWallet(txInput, signingWallet); + }); + updateInputLegendFromWallet(txInput, inputForm.getSigningWallet()); + initializeInputFields(txInput, psbtInput); initializeScriptFields(txInput, psbtInput); initializeStatusFields(txInput, psbtInput); @@ -132,9 +138,27 @@ public class InputController extends TransactionFormController implements Initia } } - private void initializeInputFields(TransactionInput txInput, PSBTInput psbtInput) { - inputFieldset.setText("Input #" + txInput.getIndex()); + private String getLegendText(TransactionInput txInput) { + return "Input #" + txInput.getIndex(); + } + private void updateInputLegendFromWallet(TransactionInput txInput, Wallet signingWallet) { + String baseText = getLegendText(txInput); + if(signingWallet != null) { + if(inputForm.isWalletTxo()) { + inputFieldset.setText(baseText + " - Wallet"); + inputFieldset.setIcon(TransactionDiagram.getTxoGlyph()); + } else { + inputFieldset.setText(baseText + " - Payjoin"); + inputFieldset.setIcon(TransactionDiagram.getPayjoinGlyph()); + } + } else { + inputFieldset.setText(baseText); + inputFieldset.setIcon(null); + } + } + + private void initializeInputFields(TransactionInput txInput, PSBTInput psbtInput) { outpoint.managedProperty().bind(outpoint.visibleProperty()); linkedOutpoint.managedProperty().bind(linkedOutpoint.visibleProperty()); diff --git a/src/main/java/com/sparrowwallet/sparrow/transaction/InputForm.java b/src/main/java/com/sparrowwallet/sparrow/transaction/InputForm.java index f03516d8..0837b30e 100644 --- a/src/main/java/com/sparrowwallet/sparrow/transaction/InputForm.java +++ b/src/main/java/com/sparrowwallet/sparrow/transaction/InputForm.java @@ -46,6 +46,11 @@ public class InputForm extends IndexedTransactionForm { return null; } + public boolean isWalletTxo() { + TransactionInput txInput = getTransactionInput(); + return getSigningWallet() != null && getSigningWallet().getWalletTxos().keySet().stream().anyMatch(ref -> ref.getHash().equals(txInput.getOutpoint().getHash()) && ref.getIndex() == txInput.getOutpoint().getIndex()); + } + @Override public Node getContents() throws IOException { FXMLLoader loader = new FXMLLoader(getClass().getResource("input.fxml")); diff --git a/src/main/java/com/sparrowwallet/sparrow/transaction/OutputController.java b/src/main/java/com/sparrowwallet/sparrow/transaction/OutputController.java index 900efd50..3d0733c3 100644 --- a/src/main/java/com/sparrowwallet/sparrow/transaction/OutputController.java +++ b/src/main/java/com/sparrowwallet/sparrow/transaction/OutputController.java @@ -1,7 +1,6 @@ package com.sparrowwallet.sparrow.transaction; import com.google.common.eventbus.Subscribe; -import com.sparrowwallet.drongo.KeyPurpose; import com.sparrowwallet.drongo.address.Address; import com.sparrowwallet.drongo.protocol.NonStandardScriptException; import com.sparrowwallet.drongo.protocol.TransactionInput; @@ -106,10 +105,10 @@ public class OutputController extends TransactionFormController implements Initi private void updateOutputLegendFromWallet(TransactionOutput txOutput, Wallet signingWallet) { String baseText = getLegendText(txOutput); if(signingWallet != null) { - if(signingWallet.getWalletOutputScripts(KeyPurpose.RECEIVE).containsKey(txOutput.getScript())) { + if(outputForm.isWalletConsolidation()) { outputFieldset.setText(baseText + " - Consolidation"); outputFieldset.setIcon(TransactionDiagram.getConsolidationGlyph()); - } else if(signingWallet.getWalletOutputScripts(KeyPurpose.CHANGE).containsKey(txOutput.getScript())) { + } else if(outputForm.isWalletChange()) { outputFieldset.setText(baseText + " - Change"); outputFieldset.setIcon(TransactionDiagram.getChangeGlyph()); } else { diff --git a/src/main/java/com/sparrowwallet/sparrow/transaction/OutputForm.java b/src/main/java/com/sparrowwallet/sparrow/transaction/OutputForm.java index 67717240..33861cf3 100644 --- a/src/main/java/com/sparrowwallet/sparrow/transaction/OutputForm.java +++ b/src/main/java/com/sparrowwallet/sparrow/transaction/OutputForm.java @@ -1,5 +1,6 @@ package com.sparrowwallet.sparrow.transaction; +import com.sparrowwallet.drongo.KeyPurpose; import com.sparrowwallet.drongo.protocol.TransactionOutput; import com.sparrowwallet.drongo.psbt.PSBTOutput; import javafx.fxml.FXMLLoader; @@ -30,6 +31,18 @@ public class OutputForm extends IndexedTransactionForm { return psbtOutput; } + public boolean isWalletConsolidation() { + return (getSigningWallet() != null && getSigningWallet().getWalletOutputScripts(KeyPurpose.RECEIVE).containsKey(getTransactionOutput().getScript())); + } + + public boolean isWalletChange() { + return (getSigningWallet() != null && getSigningWallet().getWalletOutputScripts(KeyPurpose.CHANGE).containsKey(getTransactionOutput().getScript())); + } + + public boolean isWalletPayment() { + return getSigningWallet() != null; + } + @Override public Node getContents() throws IOException { FXMLLoader loader = new FXMLLoader(getClass().getResource("output.fxml")); diff --git a/src/main/java/com/sparrowwallet/sparrow/transaction/TransactionController.java b/src/main/java/com/sparrowwallet/sparrow/transaction/TransactionController.java index d0e91a31..9784b9b5 100644 --- a/src/main/java/com/sparrowwallet/sparrow/transaction/TransactionController.java +++ b/src/main/java/com/sparrowwallet/sparrow/transaction/TransactionController.java @@ -9,6 +9,7 @@ import com.sparrowwallet.drongo.wallet.BlockTransaction; import com.sparrowwallet.sparrow.AppController; import com.sparrowwallet.sparrow.EventManager; import com.sparrowwallet.sparrow.TransactionTabData; +import com.sparrowwallet.sparrow.control.TransactionDiagram; import com.sparrowwallet.sparrow.control.TransactionHexArea; import com.sparrowwallet.sparrow.event.*; import com.sparrowwallet.sparrow.net.ElectrumServer; @@ -17,11 +18,10 @@ import javafx.fxml.FXML; import javafx.fxml.Initializable; import javafx.scene.Node; import javafx.scene.Parent; +import javafx.scene.control.TreeCell; import javafx.scene.control.TreeItem; import javafx.scene.control.TreeView; -import javafx.scene.control.cell.TextFieldTreeCell; import javafx.scene.layout.Pane; -import javafx.util.StringConverter; import org.controlsfx.control.MasterDetailPane; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -125,17 +125,46 @@ public class TransactionController implements Initializable { rootItem.getChildren().add(outputsItem); txtree.setRoot(rootItem); - txtree.setCellFactory(p -> new TextFieldTreeCell<>(new StringConverter() { + txtree.setCellFactory(tc -> new TreeCell<>() { @Override - public String toString(TransactionForm transactionForm) { - return transactionForm.toString(); - } + protected void updateItem(TransactionForm form, boolean empty) { + super.updateItem(form, empty); - @Override - public TransactionForm fromString(String string) { - throw new IllegalStateException("No editing"); + setText(null); + setGraphic(null); + setTooltip(null); + setContextMenu(null); + + if(form != null) { + setText(form.toString()); + + if(form.getSigningWallet() != null) { + if(form instanceof InputForm) { + InputForm inputForm = (InputForm)form; + if(inputForm.isWalletTxo()) { + setGraphic(TransactionDiagram.getTxoGlyph()); + } else { + setGraphic(TransactionDiagram.getPayjoinGlyph()); + } + } + if(form instanceof OutputForm) { + OutputForm outputForm = (OutputForm)form; + if(outputForm.isWalletConsolidation()) { + setGraphic(TransactionDiagram.getConsolidationGlyph()); + } else if(outputForm.isWalletChange()) { + setGraphic(TransactionDiagram.getChangeGlyph()); + } else { + setGraphic(TransactionDiagram.getPaymentGlyph()); + } + } + } + } } - })); + }); + + txdata.signingWalletProperty().addListener((observable, oldValue, newValue) -> { + txtree.refresh(); + }); txtree.getSelectionModel().selectedItemProperty().addListener((observable, old_val, selectedItem) -> { TransactionForm transactionForm = selectedItem.getValue(); diff --git a/src/main/resources/com/sparrowwallet/sparrow/darktheme.css b/src/main/resources/com/sparrowwallet/sparrow/darktheme.css index 7fbbdfed..f3ff4d65 100644 --- a/src/main/resources/com/sparrowwallet/sparrow/darktheme.css +++ b/src/main/resources/com/sparrowwallet/sparrow/darktheme.css @@ -42,7 +42,7 @@ -fx-base: -fx-accent ; } -.table-view{ +.table-view, .tree-view { /*-fx-background-color: derive(-fx-base, 10%);*/ -fx-selection-bar-non-focused: derive(-fx-base, 50%); } diff --git a/src/main/resources/com/sparrowwallet/sparrow/transaction/input.css b/src/main/resources/com/sparrowwallet/sparrow/transaction/input.css index 50896c72..8ff120d4 100644 --- a/src/main/resources/com/sparrowwallet/sparrow/transaction/input.css +++ b/src/main/resources/com/sparrowwallet/sparrow/transaction/input.css @@ -24,4 +24,7 @@ .locktime { -fx-fill: color-grey } - +.legend { + -fx-content-display: RIGHT; + -fx-graphic-text-gap: 5px; +}