diff --git a/drongo b/drongo index 5e281982..2650dafa 160000 --- a/drongo +++ b/drongo @@ -1 +1 @@ -Subproject commit 5e281982cb3f4711486f53b02b1ea9d9b12a493e +Subproject commit 2650dafa66623c1205582c555369a5118a343ccf diff --git a/src/main/java/com/sparrowwallet/sparrow/control/TextAreaDialog.java b/src/main/java/com/sparrowwallet/sparrow/control/TextAreaDialog.java index 7b9cc5ac..f0cc3333 100644 --- a/src/main/java/com/sparrowwallet/sparrow/control/TextAreaDialog.java +++ b/src/main/java/com/sparrowwallet/sparrow/control/TextAreaDialog.java @@ -5,6 +5,7 @@ import javafx.application.Platform; import javafx.beans.NamedArg; import javafx.scene.control.*; import javafx.scene.layout.HBox; +import javafx.scene.layout.Priority; public class TextAreaDialog extends Dialog { private final TextArea textArea; @@ -21,7 +22,9 @@ public class TextAreaDialog extends Dialog { this.textArea = new TextArea(defaultValue); this.textArea.setMaxWidth(Double.MAX_VALUE); this.textArea.setWrapText(true); + this.textArea.getStyleClass().add("fixed-width"); hbox.getChildren().add(textArea); + HBox.setHgrow(this.textArea, Priority.ALWAYS); this.defaultValue = defaultValue; @@ -38,6 +41,9 @@ public class TextAreaDialog extends Dialog { ButtonBar.ButtonData data = dialogButton == null ? null : dialogButton.getButtonData(); return data == ButtonBar.ButtonData.OK_DONE ? textArea.getText() : null; }); + + dialogPane.setPrefWidth(700); + dialogPane.setPrefHeight(400); } public final TextArea getEditor() { diff --git a/src/main/java/com/sparrowwallet/sparrow/wallet/KeystoreController.java b/src/main/java/com/sparrowwallet/sparrow/wallet/KeystoreController.java index edd4da14..53881d59 100644 --- a/src/main/java/com/sparrowwallet/sparrow/wallet/KeystoreController.java +++ b/src/main/java/com/sparrowwallet/sparrow/wallet/KeystoreController.java @@ -84,7 +84,7 @@ public class KeystoreController extends WalletFormController implements Initiali Platform.runLater(this::setupValidation); selectSourcePane.managedProperty().bind(selectSourcePane.visibleProperty()); - if(keystore.isValid()) { + if(keystore.isValid() || keystore.getExtendedPublicKey() != null) { selectSourcePane.setVisible(false); } @@ -303,7 +303,7 @@ public class KeystoreController extends WalletFormController implements Initiali public void update(SettingsChangedEvent event) { if(walletForm.getWallet().equals(event.getWallet()) && event.getType().equals(SettingsChangedEvent.Type.SCRIPT_TYPE)) { derivation.setPromptText(event.getWallet().getScriptType().getDefaultDerivationPath()); - if(!derivation.getText().isEmpty()) { + if(derivation.getText() != null && !derivation.getText().isEmpty()) { String derivationPath = derivation.getText(); derivation.setText(derivationPath + " "); derivation.setText(derivationPath); diff --git a/src/main/java/com/sparrowwallet/sparrow/wallet/SendController.java b/src/main/java/com/sparrowwallet/sparrow/wallet/SendController.java index 3eea4fd8..c2f60dfc 100644 --- a/src/main/java/com/sparrowwallet/sparrow/wallet/SendController.java +++ b/src/main/java/com/sparrowwallet/sparrow/wallet/SendController.java @@ -562,10 +562,34 @@ public class SendController extends WalletFormController implements Initializabl @Subscribe public void walletHistoryChanged(WalletHistoryChangedEvent event) { if(event.getWallet().equals(walletForm.getWallet())) { - updateTransaction(); + if(walletTransactionProperty.get() != null && walletTransactionProperty.get().getSelectedUtxos() != null && allSelectedUtxosSpent(event.getHistoryChangedNodes())) { + clear(null); + } else { + updateTransaction(); + } } } + private boolean allSelectedUtxosSpent(List historyChangedNodes) { + Set unspentUtxos = new HashSet<>(walletTransactionProperty.get().getSelectedUtxos().keySet()); + + for(Map.Entry selectedUtxoEntry : walletTransactionProperty.get().getSelectedUtxos().entrySet()) { + BlockTransactionHashIndex utxo = selectedUtxoEntry.getKey(); + WalletNode utxoWalletNode = selectedUtxoEntry.getValue(); + + for(WalletNode changedNode : historyChangedNodes) { + if(utxoWalletNode.equals(changedNode)) { + Optional spentTxo = changedNode.getTransactionOutputs().stream().filter(txo -> txo.getHash().equals(utxo.getHash()) && txo.getIndex() == utxo.getIndex() && txo.isSpent()).findAny(); + if(spentTxo.isPresent()) { + unspentUtxos.remove(utxo); + } + } + } + } + + return unspentUtxos.isEmpty(); + } + @Subscribe public void walletEntryLabelChanged(WalletEntryLabelChangedEvent event) { if(event.getWallet().equals(walletForm.getWallet())) { diff --git a/src/main/java/com/sparrowwallet/sparrow/wallet/SettingsController.java b/src/main/java/com/sparrowwallet/sparrow/wallet/SettingsController.java index d03a0c61..b9fdc5ca 100644 --- a/src/main/java/com/sparrowwallet/sparrow/wallet/SettingsController.java +++ b/src/main/java/com/sparrowwallet/sparrow/wallet/SettingsController.java @@ -1,6 +1,7 @@ package com.sparrowwallet.sparrow.wallet; import com.google.common.eventbus.Subscribe; +import com.sparrowwallet.drongo.OutputDescriptor; import com.sparrowwallet.drongo.SecureString; import com.sparrowwallet.drongo.crypto.*; import com.sparrowwallet.drongo.policy.Policy; @@ -14,6 +15,7 @@ import com.sparrowwallet.sparrow.AppController; import com.sparrowwallet.sparrow.EventManager; import com.sparrowwallet.sparrow.control.CopyableLabel; import com.sparrowwallet.sparrow.control.DescriptorArea; +import com.sparrowwallet.sparrow.control.TextAreaDialog; import com.sparrowwallet.sparrow.control.WalletPasswordDialog; import com.sparrowwallet.sparrow.event.SettingsChangedEvent; import com.sparrowwallet.sparrow.event.StorageEvent; @@ -248,6 +250,34 @@ public class SettingsController extends WalletFormController implements Initiali } } + public void editDescriptor(ActionEvent event) { + OutputDescriptor outputDescriptor = OutputDescriptor.getOutputDescriptor(walletForm.getWallet()); + String outputDescriptorString = outputDescriptor.toString(walletForm.getWallet().isValid()); + + TextAreaDialog dialog = new TextAreaDialog(outputDescriptorString); + dialog.setTitle("Edit wallet output descriptor"); + dialog.getDialogPane().setHeaderText("Wallet output descriptor:"); + Optional text = dialog.showAndWait(); + if(text.isPresent() && !text.get().isEmpty() && !text.get().equals(outputDescriptorString)) { + try { + OutputDescriptor editedOutputDescriptor = OutputDescriptor.getOutputDescriptor(text.get()); + Wallet editedWallet = editedOutputDescriptor.toWallet(); + + editedWallet.setName(getWalletForm().getWallet().getName()); + keystoreTabs.getTabs().removeAll(keystoreTabs.getTabs()); + totalKeystores.unbind(); + totalKeystores.setValue(0); + walletForm.setWallet(editedWallet); + initialising = true; + setFieldsFromWallet(editedWallet); + + EventManager.get().post(new SettingsChangedEvent(editedWallet, SettingsChangedEvent.Type.POLICY)); + } catch(Exception e) { + AppController.showErrorDialog("Invalid output descriptor", e.getMessage()); + } + } + } + public void showAdvanced(ActionEvent event) { AdvancedDialog advancedDialog = new AdvancedDialog(walletForm.getWallet()); advancedDialog.showAndWait(); diff --git a/src/main/java/com/sparrowwallet/sparrow/wallet/SettingsWalletForm.java b/src/main/java/com/sparrowwallet/sparrow/wallet/SettingsWalletForm.java index bbc49984..6cb0db88 100644 --- a/src/main/java/com/sparrowwallet/sparrow/wallet/SettingsWalletForm.java +++ b/src/main/java/com/sparrowwallet/sparrow/wallet/SettingsWalletForm.java @@ -25,6 +25,11 @@ public class SettingsWalletForm extends WalletForm { return walletCopy; } + @Override + public void setWallet(Wallet wallet) { + this.walletCopy = wallet; + } + @Override public void revert() { this.walletCopy = super.getWallet().copy(); diff --git a/src/main/java/com/sparrowwallet/sparrow/wallet/WalletForm.java b/src/main/java/com/sparrowwallet/sparrow/wallet/WalletForm.java index 7082d1a1..43bf6e23 100644 --- a/src/main/java/com/sparrowwallet/sparrow/wallet/WalletForm.java +++ b/src/main/java/com/sparrowwallet/sparrow/wallet/WalletForm.java @@ -46,6 +46,10 @@ public class WalletForm { return storage.getWalletFile(); } + public void setWallet(Wallet wallet) { + throw new UnsupportedOperationException("Only SettingsWalletForm supports setWallet"); + } + public void revert() { throw new UnsupportedOperationException("Only SettingsWalletForm supports revert"); } diff --git a/src/main/resources/com/sparrowwallet/sparrow/darktheme.css b/src/main/resources/com/sparrowwallet/sparrow/darktheme.css index c639791a..e59907c4 100644 --- a/src/main/resources/com/sparrowwallet/sparrow/darktheme.css +++ b/src/main/resources/com/sparrowwallet/sparrow/darktheme.css @@ -101,7 +101,7 @@ -fx-border-width: 1px; } -.root .duplicate-warning { +.root .duplicate-warning, .root #transactionDiagram .fee-warning-icon { -fx-text-fill: #e06c75; } diff --git a/src/main/resources/com/sparrowwallet/sparrow/general.css b/src/main/resources/com/sparrowwallet/sparrow/general.css index 91f24283..d23eb597 100644 --- a/src/main/resources/com/sparrowwallet/sparrow/general.css +++ b/src/main/resources/com/sparrowwallet/sparrow/general.css @@ -27,7 +27,7 @@ -fx-padding: 3 5; } -.id { +.id, .fixed-width { -fx-font-size: 13px; -fx-font-family: 'Roboto Mono'; } diff --git a/src/main/resources/com/sparrowwallet/sparrow/wallet/settings.fxml b/src/main/resources/com/sparrowwallet/sparrow/wallet/settings.fxml index 4b072140..74380f19 100644 --- a/src/main/resources/com/sparrowwallet/sparrow/wallet/settings.fxml +++ b/src/main/resources/com/sparrowwallet/sparrow/wallet/settings.fxml @@ -79,6 +79,7 @@ +