mirror of
https://github.com/sparrowwallet/sparrow.git
synced 2024-12-24 12:46:45 +00:00
addresses table
This commit is contained in:
parent
3a8581da13
commit
cabd62166a
14 changed files with 419 additions and 19 deletions
|
@ -48,7 +48,7 @@ dependencies {
|
||||||
mainClassName = 'com.sparrowwallet.sparrow/com.sparrowwallet.sparrow.MainApp'
|
mainClassName = 'com.sparrowwallet.sparrow/com.sparrowwallet.sparrow.MainApp'
|
||||||
|
|
||||||
run {
|
run {
|
||||||
applicationDefaultJvmArgs = ["-Xdock:name=Sparrow", "-Xdock:icon=/Users/scy/git/sparrow/src/main/resources/sparrow.png", "--add-opens=javafx.graphics/com.sun.javafx.css=org.controlsfx.controls", "--add-opens=javafx.graphics/javafx.scene=org.controlsfx.controls", "--add-opens=javafx.controls/com.sun.javafx.scene.control.behavior=org.controlsfx.controls", "--add-opens=javafx.controls/com.sun.javafx.scene.control.inputmap=org.controlsfx.controls", "--add-opens=javafx.graphics/com.sun.javafx.scene.traversal=org.controlsfx.controls", "--add-opens=javafx.base/com.sun.javafx.event=org.controlsfx.controls"]
|
applicationDefaultJvmArgs = ["-Xdock:name=Sparrow", "-Xdock:icon=/Users/scy/git/sparrow/src/main/resources/sparrow.png", "--add-opens=javafx.graphics/com.sun.javafx.css=org.controlsfx.controls", "--add-opens=javafx.graphics/javafx.scene=org.controlsfx.controls", "--add-opens=javafx.controls/com.sun.javafx.scene.control.behavior=org.controlsfx.controls", "--add-opens=javafx.controls/com.sun.javafx.scene.control.inputmap=org.controlsfx.controls", "--add-opens=javafx.graphics/com.sun.javafx.scene.traversal=org.controlsfx.controls", "--add-opens=javafx.base/com.sun.javafx.event=org.controlsfx.controls", "--add-opens=javafx.controls/javafx.scene.control.cell=com.sparrowwallet.sparrow"]
|
||||||
}
|
}
|
||||||
|
|
||||||
jlink {
|
jlink {
|
||||||
|
@ -63,7 +63,7 @@ jlink {
|
||||||
options = ['--strip-debug', '--compress', '2', '--no-header-files', '--no-man-pages', '--ignore-signing-information', '--exclude-files', '**.png']
|
options = ['--strip-debug', '--compress', '2', '--no-header-files', '--no-man-pages', '--ignore-signing-information', '--exclude-files', '**.png']
|
||||||
launcher {
|
launcher {
|
||||||
name = 'sparrow'
|
name = 'sparrow'
|
||||||
jvmArgs = ["--add-opens=javafx.graphics/com.sun.javafx.css=org.controlsfx.controls", "--add-opens=javafx.graphics/javafx.scene=org.controlsfx.controls", "--add-opens=javafx.controls/com.sun.javafx.scene.control.behavior=org.controlsfx.controls", "--add-opens=javafx.controls/com.sun.javafx.scene.control.inputmap=org.controlsfx.controls", "--add-opens=javafx.graphics/com.sun.javafx.scene.traversal=org.controlsfx.controls", "--add-opens=javafx.base/com.sun.javafx.event=org.controlsfx.controls"]
|
jvmArgs = ["--add-opens=javafx.graphics/com.sun.javafx.css=org.controlsfx.controls", "--add-opens=javafx.graphics/javafx.scene=org.controlsfx.controls", "--add-opens=javafx.controls/com.sun.javafx.scene.control.behavior=org.controlsfx.controls", "--add-opens=javafx.controls/com.sun.javafx.scene.control.inputmap=org.controlsfx.controls", "--add-opens=javafx.graphics/com.sun.javafx.scene.traversal=org.controlsfx.controls", "--add-opens=javafx.base/com.sun.javafx.event=org.controlsfx.controls", "--add-opens=javafx.controls/javafx.scene.control.cell=com.sparrowwallet.sparrow"]
|
||||||
}
|
}
|
||||||
addExtraDependencies("javafx")
|
addExtraDependencies("javafx")
|
||||||
jpackage {
|
jpackage {
|
||||||
|
|
2
drongo
2
drongo
|
@ -1 +1 @@
|
||||||
Subproject commit de70f44535916f93d18f66190a217d93f94e1240
|
Subproject commit eabcf4e8f48ae18ff8d21436a2ab5e5153719944
|
|
@ -252,12 +252,13 @@ public class AppController implements Initializable {
|
||||||
FileType fileType = IOUtils.getFileType(file);
|
FileType fileType = IOUtils.getFileType(file);
|
||||||
if(FileType.JSON.equals(fileType)) {
|
if(FileType.JSON.equals(fileType)) {
|
||||||
Wallet wallet = storage.loadWallet();
|
Wallet wallet = storage.loadWallet();
|
||||||
|
restorePublicKeysFromSeed(wallet, null);
|
||||||
Tab tab = addWalletTab(storage, wallet);
|
Tab tab = addWalletTab(storage, wallet);
|
||||||
tabs.getSelectionModel().select(tab);
|
tabs.getSelectionModel().select(tab);
|
||||||
} else if(FileType.BINARY.equals(fileType)) {
|
} else if(FileType.BINARY.equals(fileType)) {
|
||||||
WalletPasswordDialog dlg = new WalletPasswordDialog(WalletPasswordDialog.PasswordRequirement.LOAD);
|
WalletPasswordDialog dlg = new WalletPasswordDialog(WalletPasswordDialog.PasswordRequirement.LOAD);
|
||||||
Optional<SecureString> optionalPassword = dlg.showAndWait();
|
Optional<SecureString> optionalPassword = dlg.showAndWait();
|
||||||
if(!optionalPassword.isPresent()) {
|
if(optionalPassword.isEmpty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,295 @@
|
||||||
|
package com.sparrowwallet.sparrow.control;
|
||||||
|
|
||||||
|
import com.sparrowwallet.drongo.Utils;
|
||||||
|
import com.sparrowwallet.drongo.address.Address;
|
||||||
|
import com.sparrowwallet.drongo.protocol.Transaction;
|
||||||
|
import com.sparrowwallet.drongo.wallet.Wallet;
|
||||||
|
import com.sparrowwallet.sparrow.EventManager;
|
||||||
|
import com.sparrowwallet.sparrow.event.ReceiveActionEvent;
|
||||||
|
import javafx.beans.property.ReadOnlyObjectWrapper;
|
||||||
|
import javafx.beans.property.SimpleStringProperty;
|
||||||
|
import javafx.beans.property.StringProperty;
|
||||||
|
import javafx.event.Event;
|
||||||
|
import javafx.geometry.Pos;
|
||||||
|
import javafx.scene.control.*;
|
||||||
|
import javafx.scene.control.cell.TextFieldTreeTableCell;
|
||||||
|
import javafx.scene.input.Clipboard;
|
||||||
|
import javafx.scene.input.ClipboardContent;
|
||||||
|
import javafx.scene.layout.HBox;
|
||||||
|
import javafx.scene.text.Font;
|
||||||
|
import javafx.util.converter.DefaultStringConverter;
|
||||||
|
import org.controlsfx.glyphfont.FontAwesome;
|
||||||
|
import org.controlsfx.glyphfont.Glyph;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
|
public class AddressTreeTable extends TreeTableView<AddressTreeTable.Data> {
|
||||||
|
public void initialize(Wallet.Node rootNode) {
|
||||||
|
getStyleClass().add("address-treetable");
|
||||||
|
|
||||||
|
String address = null;
|
||||||
|
Data rootData = new Data(rootNode);
|
||||||
|
TreeItem<Data> rootItem = new TreeItem<>(rootData);
|
||||||
|
for(Wallet.Node childNode : rootNode.getChildren()) {
|
||||||
|
Data childData = new Data(childNode);
|
||||||
|
TreeItem<Data> childItem = new TreeItem<>(childData);
|
||||||
|
rootItem.getChildren().add(childItem);
|
||||||
|
address = childNode.getAddress().toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
rootItem.setExpanded(true);
|
||||||
|
setRoot(rootItem);
|
||||||
|
setShowRoot(false);
|
||||||
|
|
||||||
|
TreeTableColumn<Data, Data> addressCol = new TreeTableColumn<>("Address / Outpoints");
|
||||||
|
addressCol.setCellValueFactory((TreeTableColumn.CellDataFeatures<Data, Data> param) -> {
|
||||||
|
return new ReadOnlyObjectWrapper<>(param.getValue().getValue());
|
||||||
|
});
|
||||||
|
addressCol.setCellFactory(p -> new DataCell());
|
||||||
|
addressCol.setSortable(false);
|
||||||
|
getColumns().add(addressCol);
|
||||||
|
|
||||||
|
if(address != null) {
|
||||||
|
addressCol.setMinWidth(TextUtils.computeTextWidth(Font.font("Courier"), address, 0.0));
|
||||||
|
}
|
||||||
|
|
||||||
|
TreeTableColumn<Data, String> labelCol = new TreeTableColumn<>("Label");
|
||||||
|
labelCol.setCellValueFactory((TreeTableColumn.CellDataFeatures<Data, String> param) -> {
|
||||||
|
return param.getValue().getValue().getLabelProperty();
|
||||||
|
});
|
||||||
|
labelCol.setCellFactory(p -> new LabelCell());
|
||||||
|
labelCol.setSortable(false);
|
||||||
|
getColumns().add(labelCol);
|
||||||
|
|
||||||
|
TreeTableColumn<Data, Long> amountCol = new TreeTableColumn<>("Amount");
|
||||||
|
amountCol.setCellValueFactory((TreeTableColumn.CellDataFeatures<Data, Long> param) -> {
|
||||||
|
return new ReadOnlyObjectWrapper<>(param.getValue().getValue().getAmount());
|
||||||
|
});
|
||||||
|
amountCol.setCellFactory(p -> new AmountCell());
|
||||||
|
amountCol.setSortable(false);
|
||||||
|
getColumns().add(amountCol);
|
||||||
|
|
||||||
|
TreeTableColumn<Data, Void> actionCol = new TreeTableColumn<>("Actions");
|
||||||
|
actionCol.setCellFactory(p -> new ActionCell());
|
||||||
|
actionCol.setSortable(false);
|
||||||
|
getColumns().add(actionCol);
|
||||||
|
|
||||||
|
setEditable(true);
|
||||||
|
setColumnResizePolicy(TreeTableView.CONSTRAINED_RESIZE_POLICY);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Data {
|
||||||
|
private final Wallet.Node walletNode;
|
||||||
|
private final SimpleStringProperty labelProperty;
|
||||||
|
private final Long amount;
|
||||||
|
|
||||||
|
public Data(Wallet.Node walletNode) {
|
||||||
|
this.walletNode = walletNode;
|
||||||
|
|
||||||
|
labelProperty = new SimpleStringProperty(walletNode.getLabel());
|
||||||
|
labelProperty.addListener((observable, oldValue, newValue) -> walletNode.setLabel(newValue));
|
||||||
|
|
||||||
|
amount = walletNode.getAmount();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Wallet.Node getWalletNode() {
|
||||||
|
return walletNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getLabel() {
|
||||||
|
return labelProperty.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public StringProperty getLabelProperty() {
|
||||||
|
return labelProperty;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getAmount() {
|
||||||
|
return amount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class DataCell extends TreeTableCell<Data, Data> {
|
||||||
|
public DataCell() {
|
||||||
|
super();
|
||||||
|
getStyleClass().add("data-cell");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void updateItem(Data data, boolean empty) {
|
||||||
|
super.updateItem(data, empty);
|
||||||
|
|
||||||
|
if(empty) {
|
||||||
|
setText(null);
|
||||||
|
setGraphic(null);
|
||||||
|
} else {
|
||||||
|
if(data.getWalletNode() != null) {
|
||||||
|
Address address = data.getWalletNode().getAddress();
|
||||||
|
setText(address.toString());
|
||||||
|
setContextMenu(new AddressContextMenu(address));
|
||||||
|
} else {
|
||||||
|
//TODO: Add transaction outpoint
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class AddressContextMenu extends ContextMenu {
|
||||||
|
public AddressContextMenu(Address address) {
|
||||||
|
MenuItem copyAddress = new MenuItem("Copy Address");
|
||||||
|
copyAddress.setOnAction(AE -> {
|
||||||
|
hide();
|
||||||
|
ClipboardContent content = new ClipboardContent();
|
||||||
|
content.putString(address.toString());
|
||||||
|
Clipboard.getSystemClipboard().setContent(content);
|
||||||
|
});
|
||||||
|
|
||||||
|
MenuItem copyHex = new MenuItem("Copy Script Output Bytes");
|
||||||
|
copyHex.setOnAction(AE -> {
|
||||||
|
hide();
|
||||||
|
ClipboardContent content = new ClipboardContent();
|
||||||
|
content.putString(Utils.bytesToHex(address.getOutputScriptData()));
|
||||||
|
Clipboard.getSystemClipboard().setContent(content);
|
||||||
|
});
|
||||||
|
|
||||||
|
getItems().addAll(copyAddress, copyHex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class LabelCell extends TextFieldTreeTableCell<Data, String> {
|
||||||
|
public LabelCell() {
|
||||||
|
super(new DefaultStringConverter());
|
||||||
|
getStyleClass().add("label-cell");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateItem(String label, boolean empty) {
|
||||||
|
super.updateItem(label, empty);
|
||||||
|
|
||||||
|
if(empty) {
|
||||||
|
setText(null);
|
||||||
|
setGraphic(null);
|
||||||
|
} else {
|
||||||
|
setText(label);
|
||||||
|
setContextMenu(new LabelContextMenu(label));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void commitEdit(String label) {
|
||||||
|
// This block is necessary to support commit on losing focus, because
|
||||||
|
// the baked-in mechanism sets our editing state to false before we can
|
||||||
|
// intercept the loss of focus. The default commitEdit(...) method
|
||||||
|
// simply bails if we are not editing...
|
||||||
|
if (!isEditing() && !label.equals(getItem())) {
|
||||||
|
TreeTableView<Data> treeTable = getTreeTableView();
|
||||||
|
if(treeTable != null) {
|
||||||
|
TreeTableColumn<Data, String> column = getTableColumn();
|
||||||
|
TreeTableColumn.CellEditEvent<Data, String> event = new TreeTableColumn.CellEditEvent<>(
|
||||||
|
treeTable, new TreeTablePosition<>(treeTable, getIndex(), column),
|
||||||
|
TreeTableColumn.editCommitEvent(), label
|
||||||
|
);
|
||||||
|
Event.fireEvent(column, event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
super.commitEdit(label);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void startEdit() {
|
||||||
|
super.startEdit();
|
||||||
|
|
||||||
|
try {
|
||||||
|
Field f = getClass().getSuperclass().getDeclaredField("textField");
|
||||||
|
f.setAccessible(true);
|
||||||
|
TextField textField = (TextField)f.get(this);
|
||||||
|
textField.focusedProperty().addListener((obs, wasFocused, isNowFocused) -> {
|
||||||
|
if (!isNowFocused) {
|
||||||
|
commitEdit(getConverter().fromString(textField.getText()));
|
||||||
|
setText(getConverter().fromString(textField.getText()));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class LabelContextMenu extends ContextMenu {
|
||||||
|
public LabelContextMenu(String label) {
|
||||||
|
MenuItem copyLabel = new MenuItem("Copy Label");
|
||||||
|
copyLabel.setOnAction(AE -> {
|
||||||
|
hide();
|
||||||
|
ClipboardContent content = new ClipboardContent();
|
||||||
|
content.putString(label);
|
||||||
|
Clipboard.getSystemClipboard().setContent(content);
|
||||||
|
});
|
||||||
|
|
||||||
|
getItems().add(copyLabel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class AmountCell extends TreeTableCell<Data, Long> {
|
||||||
|
public AmountCell() {
|
||||||
|
super();
|
||||||
|
getStyleClass().add("amount-cell");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void updateItem(Long amount, boolean empty) {
|
||||||
|
super.updateItem(amount, empty);
|
||||||
|
|
||||||
|
if(empty || amount == null) {
|
||||||
|
setText(null);
|
||||||
|
setGraphic(null);
|
||||||
|
} else {
|
||||||
|
String satsValue = String.format(Locale.ENGLISH, "%,d", amount) + " sats";
|
||||||
|
String btcValue = CoinLabel.BTC_FORMAT.format(amount.doubleValue() / Transaction.SATOSHIS_PER_BITCOIN) + " BTC";
|
||||||
|
Tooltip tooltip = new Tooltip();
|
||||||
|
if(amount > CoinLabel.MAX_SATS_SHOWN) {
|
||||||
|
tooltip.setText(satsValue);
|
||||||
|
setText(btcValue);
|
||||||
|
} else {
|
||||||
|
tooltip.setText(btcValue);
|
||||||
|
setText(satsValue);
|
||||||
|
}
|
||||||
|
setTooltip(tooltip);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class ActionCell extends TreeTableCell<Data, Void> {
|
||||||
|
private final HBox actionBox;
|
||||||
|
|
||||||
|
public ActionCell() {
|
||||||
|
super();
|
||||||
|
getStyleClass().add("action-cell");
|
||||||
|
|
||||||
|
actionBox = new HBox();
|
||||||
|
actionBox.setSpacing(8);
|
||||||
|
actionBox.setAlignment(Pos.CENTER);
|
||||||
|
|
||||||
|
Button receiveButton = new Button("");
|
||||||
|
Glyph receiveGlyph = new Glyph("FontAwesome", FontAwesome.Glyph.ARROW_DOWN);
|
||||||
|
receiveGlyph.setFontSize(12);
|
||||||
|
receiveButton.setGraphic(receiveGlyph);
|
||||||
|
receiveButton.setOnAction(event -> {
|
||||||
|
EventManager.get().post(new ReceiveActionEvent(getTreeTableView().getTreeItem(getIndex()).getValue().getWalletNode()));
|
||||||
|
});
|
||||||
|
|
||||||
|
actionBox.getChildren().add(receiveButton);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void updateItem(Void item, boolean empty) {
|
||||||
|
super.updateItem(item, empty);
|
||||||
|
if (empty) {
|
||||||
|
setGraphic(null);
|
||||||
|
} else {
|
||||||
|
setGraphic(actionBox);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -16,7 +16,7 @@ import java.util.Locale;
|
||||||
public class CoinLabel extends CopyableLabel {
|
public class CoinLabel extends CopyableLabel {
|
||||||
public static final int MAX_SATS_SHOWN = 1000000;
|
public static final int MAX_SATS_SHOWN = 1000000;
|
||||||
|
|
||||||
private DecimalFormat btcFormat = new DecimalFormat("0", DecimalFormatSymbols.getInstance(Locale.ENGLISH));
|
public static final DecimalFormat BTC_FORMAT = new DecimalFormat("0", DecimalFormatSymbols.getInstance(Locale.ENGLISH));
|
||||||
|
|
||||||
private final LongProperty value = new SimpleLongProperty();
|
private final LongProperty value = new SimpleLongProperty();
|
||||||
private Tooltip tooltip;
|
private Tooltip tooltip;
|
||||||
|
@ -28,7 +28,7 @@ public class CoinLabel extends CopyableLabel {
|
||||||
|
|
||||||
public CoinLabel(String text) {
|
public CoinLabel(String text) {
|
||||||
super(text);
|
super(text);
|
||||||
btcFormat.setMaximumFractionDigits(8);
|
BTC_FORMAT.setMaximumFractionDigits(8);
|
||||||
valueProperty().addListener((observable, oldValue, newValue) -> setValueAsText((Long)newValue));
|
valueProperty().addListener((observable, oldValue, newValue) -> setValueAsText((Long)newValue));
|
||||||
tooltip = new Tooltip();
|
tooltip = new Tooltip();
|
||||||
contextMenu = new CoinContextMenu();
|
contextMenu = new CoinContextMenu();
|
||||||
|
@ -51,7 +51,7 @@ public class CoinLabel extends CopyableLabel {
|
||||||
setContextMenu(contextMenu);
|
setContextMenu(contextMenu);
|
||||||
|
|
||||||
String satsValue = String.format(Locale.ENGLISH, "%,d",value) + " sats";
|
String satsValue = String.format(Locale.ENGLISH, "%,d",value) + " sats";
|
||||||
String btcValue = btcFormat.format(value.doubleValue() / Transaction.SATOSHIS_PER_BITCOIN) + " BTC";
|
String btcValue = BTC_FORMAT.format(value.doubleValue() / Transaction.SATOSHIS_PER_BITCOIN) + " BTC";
|
||||||
if(value > MAX_SATS_SHOWN) {
|
if(value > MAX_SATS_SHOWN) {
|
||||||
tooltip.setText(satsValue);
|
tooltip.setText(satsValue);
|
||||||
setText(btcValue);
|
setText(btcValue);
|
||||||
|
@ -78,7 +78,7 @@ public class CoinLabel extends CopyableLabel {
|
||||||
copyBtcValue.setOnAction(AE -> {
|
copyBtcValue.setOnAction(AE -> {
|
||||||
hide();
|
hide();
|
||||||
ClipboardContent content = new ClipboardContent();
|
ClipboardContent content = new ClipboardContent();
|
||||||
content.putString(btcFormat.format((double)getValue() / Transaction.SATOSHIS_PER_BITCOIN));
|
content.putString(BTC_FORMAT.format((double)getValue() / Transaction.SATOSHIS_PER_BITCOIN));
|
||||||
Clipboard.getSystemClipboard().setContent(content);
|
Clipboard.getSystemClipboard().setContent(content);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -2,10 +2,7 @@ package com.sparrowwallet.sparrow.control;
|
||||||
|
|
||||||
import com.sparrowwallet.drongo.KeyDerivation;
|
import com.sparrowwallet.drongo.KeyDerivation;
|
||||||
import com.sparrowwallet.drongo.crypto.ChildNumber;
|
import com.sparrowwallet.drongo.crypto.ChildNumber;
|
||||||
import com.sparrowwallet.drongo.wallet.Bip39MnemonicCode;
|
import com.sparrowwallet.drongo.wallet.*;
|
||||||
import com.sparrowwallet.drongo.wallet.DeterministicSeed;
|
|
||||||
import com.sparrowwallet.drongo.wallet.Keystore;
|
|
||||||
import com.sparrowwallet.drongo.wallet.Wallet;
|
|
||||||
import com.sparrowwallet.sparrow.EventManager;
|
import com.sparrowwallet.sparrow.EventManager;
|
||||||
import com.sparrowwallet.sparrow.event.KeystoreImportEvent;
|
import com.sparrowwallet.sparrow.event.KeystoreImportEvent;
|
||||||
import com.sparrowwallet.sparrow.io.*;
|
import com.sparrowwallet.sparrow.io.*;
|
||||||
|
@ -244,7 +241,9 @@ public class MnemonicKeystoreImportPane extends TitledDescriptionPane {
|
||||||
return true;
|
return true;
|
||||||
} catch (ImportException e) {
|
} catch (ImportException e) {
|
||||||
String errorMessage = e.getMessage();
|
String errorMessage = e.getMessage();
|
||||||
if(e.getCause() != null && e.getCause().getMessage() != null && !e.getCause().getMessage().isEmpty()) {
|
if(e.getCause() instanceof MnemonicException.MnemonicChecksumException) {
|
||||||
|
errorMessage = "Invalid word list - checksum incorrect";
|
||||||
|
} else if(e.getCause() != null && e.getCause().getMessage() != null && !e.getCause().getMessage().isEmpty()) {
|
||||||
errorMessage = e.getCause().getMessage();
|
errorMessage = e.getCause().getMessage();
|
||||||
}
|
}
|
||||||
setError("Import Error", errorMessage);
|
setError("Import Error", errorMessage);
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
package com.sparrowwallet.sparrow.event;
|
||||||
|
|
||||||
|
import com.sparrowwallet.drongo.wallet.Wallet;
|
||||||
|
|
||||||
|
public class ReceiveActionEvent {
|
||||||
|
private Wallet.Node receiveNode;
|
||||||
|
|
||||||
|
public ReceiveActionEvent(Wallet.Node receiveNode) {
|
||||||
|
this.receiveNode = receiveNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Wallet.Node getReceiveNode() {
|
||||||
|
return receiveNode;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
package com.sparrowwallet.sparrow.wallet;
|
||||||
|
|
||||||
|
import com.sparrowwallet.drongo.KeyPurpose;
|
||||||
|
import com.sparrowwallet.drongo.wallet.Wallet;
|
||||||
|
import com.sparrowwallet.sparrow.EventManager;
|
||||||
|
import com.sparrowwallet.sparrow.control.AddressTreeTable;
|
||||||
|
import javafx.fxml.FXML;
|
||||||
|
import javafx.fxml.Initializable;
|
||||||
|
|
||||||
|
import java.net.URL;
|
||||||
|
import java.util.ResourceBundle;
|
||||||
|
|
||||||
|
public class AddressesController extends WalletFormController implements Initializable {
|
||||||
|
@FXML
|
||||||
|
private AddressTreeTable receiveTable;
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
private AddressTreeTable changeTable;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void initialize(URL location, ResourceBundle resources) {
|
||||||
|
EventManager.get().register(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void initializeView() {
|
||||||
|
Wallet wallet = walletForm.getWallet();
|
||||||
|
|
||||||
|
receiveTable.initialize(wallet.getNodes(KeyPurpose.RECEIVE));
|
||||||
|
changeTable.initialize(wallet.getNodes(KeyPurpose.CHANGE));
|
||||||
|
}
|
||||||
|
}
|
|
@ -47,9 +47,9 @@ public class WalletController extends WalletFormController implements Initializa
|
||||||
for(Node walletFunction : walletPane.getChildren()) {
|
for(Node walletFunction : walletPane.getChildren()) {
|
||||||
if(walletFunction.getUserData().equals(function)) {
|
if(walletFunction.getUserData().equals(function)) {
|
||||||
existing = true;
|
existing = true;
|
||||||
walletFunction.setViewOrder(1);
|
|
||||||
} else {
|
|
||||||
walletFunction.setViewOrder(0);
|
walletFunction.setViewOrder(0);
|
||||||
|
} else {
|
||||||
|
walletFunction.setViewOrder(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,6 +57,7 @@ public class WalletController extends WalletFormController implements Initializa
|
||||||
if(!existing) {
|
if(!existing) {
|
||||||
FXMLLoader functionLoader = new FXMLLoader(AppController.class.getResource("wallet/" + function.toString().toLowerCase() + ".fxml"));
|
FXMLLoader functionLoader = new FXMLLoader(AppController.class.getResource("wallet/" + function.toString().toLowerCase() + ".fxml"));
|
||||||
Node walletFunction = functionLoader.load();
|
Node walletFunction = functionLoader.load();
|
||||||
|
walletFunction.setUserData(function);
|
||||||
WalletFormController controller = functionLoader.getController();
|
WalletFormController controller = functionLoader.getController();
|
||||||
controller.setWalletForm(getWalletForm());
|
controller.setWalletForm(getWalletForm());
|
||||||
walletFunction.setViewOrder(1);
|
walletFunction.setViewOrder(1);
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
.address-treetable-label {
|
||||||
|
-fx-font-weight: bold;
|
||||||
|
-fx-font-size: 1.2em;
|
||||||
|
-fx-padding: 10 0 10 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.data-cell {
|
||||||
|
-fx-font-family: Courier;
|
||||||
|
}
|
||||||
|
|
||||||
|
.label-cell .text-field {
|
||||||
|
-fx-padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-cell .button {
|
||||||
|
-fx-padding: 0;
|
||||||
|
-fx-pref-height: 18;
|
||||||
|
-fx-pref-width: 18;
|
||||||
|
}
|
|
@ -0,0 +1,38 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
|
||||||
|
<?import java.lang.*?>
|
||||||
|
<?import java.util.*?>
|
||||||
|
<?import javafx.scene.*?>
|
||||||
|
<?import javafx.scene.control.*?>
|
||||||
|
<?import javafx.scene.layout.*?>
|
||||||
|
|
||||||
|
<?import javafx.geometry.Insets?>
|
||||||
|
<?import com.sparrowwallet.sparrow.control.AddressTreeTable?>
|
||||||
|
<GridPane hgap="10.0" vgap="10.0" stylesheets="@addresses.css, @wallet.css, @../general.css" styleClass="wallet-pane" xmlns="http://javafx.com/javafx/10.0.2-internal" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.sparrowwallet.sparrow.wallet.AddressesController">
|
||||||
|
<padding>
|
||||||
|
<Insets left="25.0" right="25.0" top="15.0" bottom="25.0" />
|
||||||
|
</padding>
|
||||||
|
<columnConstraints>
|
||||||
|
<ColumnConstraints percentWidth="100.0" />
|
||||||
|
</columnConstraints>
|
||||||
|
<rowConstraints>
|
||||||
|
<RowConstraints percentHeight="50" />
|
||||||
|
<RowConstraints percentHeight="50" />
|
||||||
|
</rowConstraints>
|
||||||
|
<BorderPane GridPane.columnIndex="0" GridPane.rowIndex="0">
|
||||||
|
<top>
|
||||||
|
<Label styleClass="address-treetable-label" text="Receiving Addresses:"/>
|
||||||
|
</top>
|
||||||
|
<center>
|
||||||
|
<AddressTreeTable fx:id="receiveTable" />
|
||||||
|
</center>
|
||||||
|
</BorderPane>
|
||||||
|
<BorderPane GridPane.columnIndex="0" GridPane.rowIndex="1">
|
||||||
|
<top>
|
||||||
|
<Label styleClass="address-treetable-label" text="Change Addresses:"/>
|
||||||
|
</top>
|
||||||
|
<center>
|
||||||
|
<AddressTreeTable fx:id="changeTable" />
|
||||||
|
</center>
|
||||||
|
</BorderPane>
|
||||||
|
</GridPane>
|
|
@ -10,7 +10,7 @@
|
||||||
<?import com.sparrowwallet.drongo.policy.PolicyType?>
|
<?import com.sparrowwallet.drongo.policy.PolicyType?>
|
||||||
<?import com.sparrowwallet.drongo.protocol.ScriptType?>
|
<?import com.sparrowwallet.drongo.protocol.ScriptType?>
|
||||||
|
|
||||||
<BorderPane stylesheets="@settings.css, @../general.css" xmlns="http://javafx.com/javafx/10.0.2-internal" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.sparrowwallet.sparrow.wallet.SettingsController">
|
<BorderPane stylesheets="@settings.css, @wallet.css, @../general.css" styleClass="wallet-pane" xmlns="http://javafx.com/javafx/10.0.2-internal" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.sparrowwallet.sparrow.wallet.SettingsController">
|
||||||
<center>
|
<center>
|
||||||
<GridPane hgap="10.0" vgap="10.0">
|
<GridPane hgap="10.0" vgap="10.0">
|
||||||
<padding>
|
<padding>
|
||||||
|
|
|
@ -25,6 +25,6 @@
|
||||||
-fx-opacity: 1;
|
-fx-opacity: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#walletPane {
|
.wallet-pane {
|
||||||
-fx-background-color: -fx-background;
|
-fx-background-color: -fx-background;
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,7 +65,7 @@
|
||||||
</VBox>
|
</VBox>
|
||||||
</left>
|
</left>
|
||||||
<center>
|
<center>
|
||||||
<StackPane fx:id="walletPane">
|
<StackPane fx:id="walletPane" styleClass="wallet-pane">
|
||||||
|
|
||||||
</StackPane>
|
</StackPane>
|
||||||
</center>
|
</center>
|
||||||
|
|
Loading…
Reference in a new issue