add settings dialog and other terminal improvements

This commit is contained in:
Craig Raw 2022-10-18 12:42:44 +02:00
parent 0fa6bd56e2
commit 8dd1850905
11 changed files with 387 additions and 36 deletions

View file

@ -36,7 +36,7 @@ public class MasterActionListBox extends ActionListBox {
.filter(entry -> entry.getValue().getWalletFile().equals(recentWalletFile)).map(Map.Entry::getKey) .filter(entry -> entry.getValue().getWalletFile().equals(recentWalletFile)).map(Map.Entry::getKey)
.map(wallet -> wallet.isMasterWallet() ? wallet : wallet.getMasterWallet()).findFirst(); .map(wallet -> wallet.isMasterWallet() ? wallet : wallet.getMasterWallet()).findFirst();
if(optWallet.isPresent()) { if(optWallet.isPresent()) {
builder.addAction(storage.getWalletName(null) + "*", () -> LoadWallet.getOpeningDialog(optWallet.get()).showDialog(SparrowTerminal.get().getGui())); builder.addAction(storage.getWalletName(null) + "*", () -> LoadWallet.getOpeningDialog(storage, optWallet.get()).showDialog(SparrowTerminal.get().getGui()));
} else { } else {
builder.addAction(storage.getWalletName(null), new LoadWallet(storage)); builder.addAction(storage.getWalletName(null), new LoadWallet(storage));
} }

View file

@ -31,10 +31,14 @@ public class SparrowTerminal extends Application {
private Screen screen; private Screen screen;
private SparrowTextGui gui; private SparrowTextGui gui;
private final Map<Wallet, WalletData> walletData = new HashMap<>(); private final Map<String, WalletData> walletData = new HashMap<>();
@Override @Override
public void init() throws Exception { public void init() throws Exception {
Thread.setDefaultUncaughtExceptionHandler((t, e) -> {
log.error("Exception in thread \"" + t.getName() + "\"", e);
});
AppServices.initialize(this, new TerminalInteractionServices()); AppServices.initialize(this, new TerminalInteractionServices());
this.terminal = new DefaultTerminalFactory().createTerminal(); this.terminal = new DefaultTerminalFactory().createTerminal();
@ -59,15 +63,7 @@ public class SparrowTerminal extends Application {
@Override @Override
public void stop() throws Exception { public void stop() throws Exception {
try {
AppServices.get().stop();
SparrowWallet.Instance instance = SparrowWallet.getSparrowInstance();
if(instance != null) {
instance.freeLock();
}
} catch(Exception e) {
log.error("Could not stop application", e);
}
} }
public Screen getScreen() { public Screen getScreen() {
@ -82,14 +78,21 @@ public class SparrowTerminal extends Application {
return gui.getGUIThread(); return gui.getGUIThread();
} }
public Map<Wallet, WalletData> getWalletData() { public Map<String, WalletData> getWalletData() {
return walletData; return walletData;
} }
public void exit() { public void exit() {
try { try {
screen.stopScreen(); screen.stopScreen();
Platform.runLater(Platform::exit); Platform.runLater(() -> {
AppServices.get().stop();
Platform.exit();
});
SparrowWallet.Instance instance = SparrowWallet.getSparrowInstance();
if(instance != null) {
instance.freeLock();
}
} catch(Exception e) { } catch(Exception e) {
log.error("Could not stop terminal screen", e); log.error("Could not stop terminal screen", e);
} }

View file

@ -40,7 +40,10 @@ public class ServerTestDialog extends DialogWindow {
this.testStatus = new Label(""); this.testStatus = new Label("");
mainPanel.addComponent(testStatus); mainPanel.addComponent(testStatus);
this.testResults = new TextBox(new TerminalSize(60, 10)); TerminalSize screenSize = SparrowTerminal.get().getScreen().getTerminalSize();
int resultsWidth = Math.min(Math.max(20, screenSize.getColumns() - 20), 100);
this.testResults = new TextBox(new TerminalSize(resultsWidth, 10));
testResults.setReadOnly(true); testResults.setReadOnly(true);
mainPanel.addComponent(testResults); mainPanel.addComponent(testResults);

View file

@ -60,7 +60,7 @@ public class AddressesDialog extends WalletDialog {
table.setSelectAction(() -> { table.setSelectAction(() -> {
NodeEntry nodeEntry = (NodeEntry)getWalletForm().getNodeEntry(keyPurpose).getChildren().get(table.getSelectedRow()); NodeEntry nodeEntry = (NodeEntry)getWalletForm().getNodeEntry(keyPurpose).getChildren().get(table.getSelectedRow());
close(); close();
WalletData walletData = SparrowTerminal.get().getWalletData().get(getWalletForm().getWallet()); WalletData walletData = SparrowTerminal.get().getWalletData().get(getWalletForm().getWalletId());
ReceiveDialog receiveDialog = walletData.getReceiveDialog(); ReceiveDialog receiveDialog = walletData.getReceiveDialog();
receiveDialog.setNodeEntry(nodeEntry); receiveDialog.setNodeEntry(nodeEntry);
receiveDialog.showDialog(SparrowTerminal.get().getGui()); receiveDialog.showDialog(SparrowTerminal.get().getGui());

View file

@ -0,0 +1,113 @@
package com.sparrowwallet.sparrow.terminal.wallet;
import com.googlecode.lanterna.TerminalSize;
import com.googlecode.lanterna.gui2.*;
import com.sparrowwallet.drongo.wallet.Wallet;
import com.sparrowwallet.sparrow.io.Storage;
import com.sparrowwallet.sparrow.wallet.WalletForm;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.regex.Pattern;
public class AdvancedDialog extends WalletDialog {
private static final DateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd");
private final TextBox birthDate;
private final TextBox gapLimit;
private final Button apply;
private Result result = Result.CANCEL;
public AdvancedDialog(WalletForm walletForm) {
super(walletForm.getWallet().getFullDisplayName() + " Advanced Settings", walletForm);
setHints(List.of(Hint.CENTERED));
Wallet wallet = getWalletForm().getWallet();
Panel mainPanel = new Panel();
mainPanel.setLayoutManager(new GridLayout(2).setHorizontalSpacing(5).setVerticalSpacing(1));
mainPanel.addComponent(new EmptySpace(TerminalSize.ONE));
mainPanel.addComponent(new EmptySpace(TerminalSize.ONE));
mainPanel.addComponent(new Label("Birth date"));
birthDate = new TextBox().setValidationPattern(Pattern.compile("[0-9\\-/]*"));
mainPanel.addComponent(birthDate);
mainPanel.addComponent(new Label("Gap limit"));
gapLimit = new TextBox().setValidationPattern(Pattern.compile("[0-9]*"));
mainPanel.addComponent(gapLimit);
Panel buttonPanel = new Panel();
buttonPanel.setLayoutManager(new GridLayout(2).setHorizontalSpacing(1));
buttonPanel.addComponent(new Button("Cancel", this::onCancel));
apply = new Button("Apply", this::onApply).setLayoutData(GridLayout.createLayoutData(GridLayout.Alignment.CENTER, GridLayout.Alignment.CENTER, true, false));
apply.setEnabled(false);
buttonPanel.addComponent(apply);
boolean noPassword = Storage.NO_PASSWORD_KEY.equals(walletForm.getStorage().getEncryptionPubKey());
mainPanel.addComponent(new Button(noPassword ? "Add Password" : "Change Password", this::onChangePassword));
buttonPanel.setLayoutData(GridLayout.createLayoutData(GridLayout.Alignment.END, GridLayout.Alignment.CENTER,false,false)).addTo(mainPanel);
setComponent(mainPanel);
if(wallet.getBirthDate() != null) {
birthDate.setText(DATE_FORMAT.format(wallet.getBirthDate()));
}
gapLimit.setText(Integer.toString(wallet.getGapLimit()));
birthDate.setTextChangeListener((newText, changedByUserInteraction) -> {
try {
Date newDate = DATE_FORMAT.parse(newText);
wallet.setBirthDate(newDate);
apply.setEnabled(true);
} catch(ParseException e) {
//ignore
}
});
gapLimit.setTextChangeListener((newText, changedByUserInteraction) -> {
try {
int newValue = Integer.parseInt(newText);
if(newValue < 0 || newValue > 1000000) {
return;
}
wallet.setGapLimit(newValue);
apply.setEnabled(true);
} catch(NumberFormatException e) {
return;
}
});
}
private void onChangePassword() {
result = Result.CHANGE_PASSWORD;
close();
}
private void onApply() {
result = Result.APPLY;
close();
}
private void onCancel() {
close();
}
@Override
public Object showDialog(WindowBasedTextGUI textGUI) {
super.showDialog(textGUI);
return result;
}
public enum Result {
CANCEL, APPLY, CHANGE_PASSWORD
}
}

View file

@ -120,7 +120,7 @@ public class LoadWallet implements Runnable {
if(walletAndKey.getWallet().isMasterWallet()) { if(walletAndKey.getWallet().isMasterWallet()) {
SparrowTerminal.get().getGuiThread().invokeLater(() -> { SparrowTerminal.get().getGuiThread().invokeLater(() -> {
SparrowTerminal.get().getGui().removeWindow(loadingDialog); SparrowTerminal.get().getGui().removeWindow(loadingDialog);
getOpeningDialog(walletAndKey.getWallet()).showDialog(SparrowTerminal.get().getGui()); getOpeningDialog(storage, walletAndKey.getWallet()).showDialog(SparrowTerminal.get().getGui());
}); });
} }
} catch(Exception e) { } catch(Exception e) {
@ -133,7 +133,7 @@ public class LoadWallet implements Runnable {
private void addWallet(Storage storage, Wallet wallet) { private void addWallet(Storage storage, Wallet wallet) {
if(wallet.isNested()) { if(wallet.isNested()) {
WalletData walletData = SparrowTerminal.get().getWalletData().get(wallet.getMasterWallet()); WalletData walletData = SparrowTerminal.get().getWalletData().get(storage.getWalletId(wallet.getMasterWallet()));
WalletForm walletForm = new WalletForm(storage, wallet); WalletForm walletForm = new WalletForm(storage, wallet);
EventManager.get().register(walletForm); EventManager.get().register(walletForm);
walletData.getWalletForm().getNestedWalletForms().add(walletForm); walletData.getWalletForm().getNestedWalletForms().add(walletForm);
@ -142,7 +142,7 @@ public class LoadWallet implements Runnable {
WalletForm walletForm = new WalletForm(storage, wallet); WalletForm walletForm = new WalletForm(storage, wallet);
EventManager.get().register(walletForm); EventManager.get().register(walletForm);
SparrowTerminal.get().getWalletData().put(wallet, new WalletData(walletForm)); SparrowTerminal.get().getWalletData().put(walletForm.getWalletId(), new WalletData(walletForm));
List<WalletTabData> walletTabDataList = SparrowTerminal.get().getWalletData().values().stream() List<WalletTabData> walletTabDataList = SparrowTerminal.get().getWalletData().values().stream()
.map(data -> new WalletTabData(TabData.TabType.WALLET, data.getWalletForm())).collect(Collectors.toList()); .map(data -> new WalletTabData(TabData.TabType.WALLET, data.getWalletForm())).collect(Collectors.toList());
@ -159,11 +159,11 @@ public class LoadWallet implements Runnable {
EventManager.get().post(new WalletOpenedEvent(storage, wallet)); EventManager.get().post(new WalletOpenedEvent(storage, wallet));
} }
public static DialogWindow getOpeningDialog(Wallet masterWallet) { public static DialogWindow getOpeningDialog(Storage storage, Wallet masterWallet) {
if(masterWallet.getChildWallets().stream().anyMatch(childWallet -> !childWallet.isNested())) { if(masterWallet.getChildWallets().stream().anyMatch(childWallet -> !childWallet.isNested())) {
return new WalletAccountsDialog(masterWallet); return new WalletAccountsDialog(storage.getWalletId(masterWallet));
} else { } else {
return new WalletActionsDialog(masterWallet); return new WalletActionsDialog(storage.getWalletId(masterWallet));
} }
} }

View file

@ -0,0 +1,208 @@
package com.sparrowwallet.sparrow.terminal.wallet;
import com.googlecode.lanterna.TerminalSize;
import com.googlecode.lanterna.gui2.*;
import com.googlecode.lanterna.gui2.dialogs.TextInputDialogBuilder;
import com.sparrowwallet.drongo.KeyPurpose;
import com.sparrowwallet.drongo.OutputDescriptor;
import com.sparrowwallet.drongo.SecureString;
import com.sparrowwallet.drongo.crypto.ECKey;
import com.sparrowwallet.drongo.crypto.EncryptionType;
import com.sparrowwallet.drongo.crypto.Key;
import com.sparrowwallet.drongo.wallet.Wallet;
import com.sparrowwallet.sparrow.AppServices;
import com.sparrowwallet.sparrow.EventManager;
import com.sparrowwallet.sparrow.event.RequestOpenWalletsEvent;
import com.sparrowwallet.sparrow.event.StorageEvent;
import com.sparrowwallet.sparrow.event.TimedEvent;
import com.sparrowwallet.sparrow.io.Storage;
import com.sparrowwallet.sparrow.io.StorageException;
import com.sparrowwallet.sparrow.terminal.SparrowTerminal;
import com.sparrowwallet.sparrow.wallet.Function;
import com.sparrowwallet.sparrow.wallet.WalletForm;
import javafx.application.Platform;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class SettingsDialog extends WalletDialog {
private static final Logger log = LoggerFactory.getLogger(SettingsDialog.class);
private final Label scriptType;
private final TextBox outputDescriptor;
public SettingsDialog(WalletForm walletForm) {
super(walletForm.getWallet().getFullDisplayName() + " Settings", walletForm);
setHints(List.of(Hint.CENTERED));
Panel mainPanel = new Panel(new GridLayout(2).setHorizontalSpacing(2).setVerticalSpacing(0).setTopMarginSize(1));
mainPanel.addComponent(new Label("Script Type"));
scriptType = new Label(getWalletForm().getWallet().getScriptType().getDescription()).addTo(mainPanel);
mainPanel.addComponent(new EmptySpace(TerminalSize.ONE));
mainPanel.addComponent(new EmptySpace(TerminalSize.ONE));
TerminalSize screenSize = SparrowTerminal.get().getScreen().getTerminalSize();
int descriptorWidth = Math.min(Math.max(20, screenSize.getColumns() - 20), 120);
OutputDescriptor descriptor = OutputDescriptor.getOutputDescriptor(getWalletForm().getWallet(), KeyPurpose.DEFAULT_PURPOSES, null);
String outputDescriptorString = descriptor.toString(true);
List<String> outputDescriptorLines = splitString(outputDescriptorString, descriptorWidth);
mainPanel.addComponent(new Label("Output Descriptor"));
outputDescriptor = new TextBox(new TerminalSize(descriptorWidth, Math.min(outputDescriptorLines.size(), 10)));
outputDescriptor.setReadOnly(true);
outputDescriptor.setText(outputDescriptorLines.stream().reduce((s1, s2) -> s1 + "\n" + s2).get());
mainPanel.addComponent(new EmptySpace(TerminalSize.ONE));
mainPanel.addComponent(outputDescriptor, GridLayout.createLayoutData(GridLayout.Alignment.BEGINNING, GridLayout.Alignment.CENTER, true, true, 2, 1));
mainPanel.addComponent(new EmptySpace(TerminalSize.ONE));
mainPanel.addComponent(new EmptySpace(TerminalSize.ONE));
Panel buttonPanel = new Panel();
buttonPanel.setLayoutManager(new GridLayout(2).setHorizontalSpacing(1));
buttonPanel.addComponent(new Button("Back", () -> onBack(Function.SETTINGS)));
buttonPanel.addComponent(new Button("Advanced", this::showAdvanced).setLayoutData(GridLayout.createLayoutData(GridLayout.Alignment.CENTER, GridLayout.Alignment.CENTER, true, false)));
mainPanel.addComponent(new EmptySpace(TerminalSize.ONE));
buttonPanel.setLayoutData(GridLayout.createLayoutData(GridLayout.Alignment.END, GridLayout.Alignment.CENTER,false,false)).addTo(mainPanel);
setComponent(mainPanel);
}
private void showAdvanced() {
AdvancedDialog advancedDialog = new AdvancedDialog(getWalletForm());
AdvancedDialog.Result result = (AdvancedDialog.Result)advancedDialog.showDialog(SparrowTerminal.get().getGui());
if(result != AdvancedDialog.Result.CANCEL) {
saveWallet(false, result == AdvancedDialog.Result.CHANGE_PASSWORD);
}
}
private void saveWallet(boolean changePassword, boolean suggestChangePassword) {
WalletForm walletForm = getWalletForm();
ECKey existingPubKey = walletForm.getStorage().getEncryptionPubKey();
PasswordRequirement requirement;
if(existingPubKey == null) {
if(changePassword) {
requirement = PasswordRequirement.UPDATE_CHANGE;
} else {
requirement = PasswordRequirement.UPDATE_NEW;
}
} else if(Storage.NO_PASSWORD_KEY.equals(existingPubKey)) {
requirement = PasswordRequirement.UPDATE_EMPTY;
} else {
requirement = PasswordRequirement.UPDATE_SET;
}
TextInputDialogBuilder builder = new TextInputDialogBuilder().setTitle("Wallet Password");
builder.setDescription(requirement.description);
builder.setPasswordInput(true);
String password = builder.build().showDialog(SparrowTerminal.get().getGui());
if(password != null) {
Platform.runLater(() -> {
if(password.length() == 0 && requirement != PasswordRequirement.UPDATE_SET) {
try {
walletForm.getStorage().setEncryptionPubKey(Storage.NO_PASSWORD_KEY);
walletForm.saveAndRefresh();
EventManager.get().post(new RequestOpenWalletsEvent());
} catch (IOException | StorageException e) {
log.error("Error saving wallet", e);
AppServices.showErrorDialog("Error saving wallet", e.getMessage());
}
} else {
Storage.KeyDerivationService keyDerivationService = new Storage.KeyDerivationService(walletForm.getStorage(), new SecureString(password));
keyDerivationService.setOnSucceeded(workerStateEvent -> {
EventManager.get().post(new StorageEvent(walletForm.getWalletId(), TimedEvent.Action.END, "Done"));
ECKey encryptionFullKey = keyDerivationService.getValue();
Key key = null;
try {
ECKey encryptionPubKey = ECKey.fromPublicOnly(encryptionFullKey);
if(existingPubKey != null && !Storage.NO_PASSWORD_KEY.equals(existingPubKey) && !existingPubKey.equals(encryptionPubKey)) {
AppServices.showErrorDialog("Incorrect Password", "The password was incorrect.");
return;
}
key = new Key(encryptionFullKey.getPrivKeyBytes(), walletForm.getStorage().getKeyDeriver().getSalt(), EncryptionType.Deriver.ARGON2);
Wallet masterWallet = walletForm.getWallet().isMasterWallet() ? walletForm.getWallet() : walletForm.getWallet().getMasterWallet();
if(suggestChangePassword && requirement == PasswordRequirement.UPDATE_SET) {
walletForm.getStorage().setEncryptionPubKey(null);
masterWallet.decrypt(key);
for(Wallet childWallet : masterWallet.getChildWallets()) {
if(!childWallet.isNested()) {
childWallet.decrypt(key);
}
}
SparrowTerminal.get().getGuiThread().invokeLater(() -> saveWallet(true, false));
return;
}
masterWallet.encrypt(key);
for(Wallet childWallet : masterWallet.getChildWallets()) {
if(!childWallet.isNested()) {
childWallet.encrypt(key);
}
}
walletForm.getStorage().setEncryptionPubKey(encryptionPubKey);
walletForm.saveAndRefresh();
EventManager.get().post(new RequestOpenWalletsEvent());
} catch (Exception e) {
log.error("Error saving wallet", e);
AppServices.showErrorDialog("Error saving wallet", e.getMessage());
} finally {
encryptionFullKey.clear();
if(key != null) {
key.clear();
}
}
});
keyDerivationService.setOnFailed(workerStateEvent -> {
EventManager.get().post(new StorageEvent(walletForm.getWalletId(), TimedEvent.Action.END, "Failed"));
AppServices.showErrorDialog("Error saving wallet", keyDerivationService.getException().getMessage());
});
EventManager.get().post(new StorageEvent(walletForm.getWalletId(), TimedEvent.Action.START, "Encrypting wallet..."));
keyDerivationService.start();
}
});
}
}
public static List<String> splitString(String stringToSplit, int maxLength) {
String text = stringToSplit;
List<String> lines = new ArrayList<>();
while(text.length() > maxLength) {
int breakAt = maxLength - 1;
lines.add(text.substring(0, breakAt));
text = text.substring(breakAt + 1);
}
lines.add(text);
return lines;
}
public enum PasswordRequirement {
UPDATE_NEW("Add a password to the wallet?\nLeave empty for no password:", "No Password"),
UPDATE_EMPTY("This wallet has no password.\nAdd a password to the wallet?\nLeave empty for no password:", "No Password"),
UPDATE_SET("Re-enter the wallet password:", "Verify Password"),
UPDATE_CHANGE("Enter the new wallet password.\nLeave empty for no password:", "No Password");
private final String description;
private final String okButtonText;
PasswordRequirement(String description, String okButtonText) {
this.description = description;
this.okButtonText = okButtonText;
}
}
}

View file

@ -4,20 +4,23 @@ import com.googlecode.lanterna.TerminalSize;
import com.googlecode.lanterna.gui2.*; import com.googlecode.lanterna.gui2.*;
import com.googlecode.lanterna.gui2.dialogs.DialogWindow; import com.googlecode.lanterna.gui2.dialogs.DialogWindow;
import com.sparrowwallet.drongo.wallet.Wallet; import com.sparrowwallet.drongo.wallet.Wallet;
import com.sparrowwallet.sparrow.io.Storage;
import com.sparrowwallet.sparrow.terminal.SparrowTerminal; import com.sparrowwallet.sparrow.terminal.SparrowTerminal;
import com.sparrowwallet.sparrow.wallet.WalletForm;
import java.util.List; import java.util.List;
public class WalletAccountsDialog extends DialogWindow { public class WalletAccountsDialog extends DialogWindow {
private final Wallet masterWallet;
private final ActionListBox actions; private final ActionListBox actions;
public WalletAccountsDialog(Wallet masterWallet) { public WalletAccountsDialog(String masterWalletId) {
super(masterWallet.getFullDisplayName()); super(SparrowTerminal.get().getWalletData().get(masterWalletId).getWalletForm().getWallet().getName());
setHints(List.of(Hint.CENTERED)); setHints(List.of(Hint.CENTERED));
this.masterWallet = masterWallet; WalletForm masterWalletForm = SparrowTerminal.get().getWalletData().get(masterWalletId).getWalletForm();
Storage storage = masterWalletForm.getStorage();
Wallet masterWallet = masterWalletForm.getWallet();
actions = new ActionListBox(); actions = new ActionListBox();
@ -25,7 +28,7 @@ public class WalletAccountsDialog extends DialogWindow {
actions.addItem(wallet.getDisplayName(), () -> { actions.addItem(wallet.getDisplayName(), () -> {
close(); close();
SparrowTerminal.get().getGuiThread().invokeLater(() -> { SparrowTerminal.get().getGuiThread().invokeLater(() -> {
WalletActionsDialog walletActionsDialog = new WalletActionsDialog(wallet); WalletActionsDialog walletActionsDialog = new WalletActionsDialog(storage.getWalletId(wallet));
walletActionsDialog.showDialog(SparrowTerminal.get().getGui()); walletActionsDialog.showDialog(SparrowTerminal.get().getGui());
}); });
}); });

View file

@ -10,15 +10,15 @@ import com.sparrowwallet.sparrow.wallet.Function;
import java.util.List; import java.util.List;
public class WalletActionsDialog extends DialogWindow { public class WalletActionsDialog extends DialogWindow {
private final Wallet wallet; private final String walletId;
private final ActionListBox actions; private final ActionListBox actions;
public WalletActionsDialog(Wallet wallet) { public WalletActionsDialog(String walletId) {
super(wallet.getFullDisplayName()); super(SparrowTerminal.get().getWalletData().get(walletId).getWalletForm().getWallet().getFullDisplayName());
setHints(List.of(Hint.CENTERED)); setHints(List.of(Hint.CENTERED));
this.wallet = wallet; this.walletId = walletId;
actions = new ActionListBox(); actions = new ActionListBox();
actions.addItem("Transactions", () -> { actions.addItem("Transactions", () -> {
@ -43,6 +43,11 @@ public class WalletActionsDialog extends DialogWindow {
UtxosDialog utxosDialog = getWalletData().getUtxosDialog(); UtxosDialog utxosDialog = getWalletData().getUtxosDialog();
utxosDialog.showDialog(SparrowTerminal.get().getGui()); utxosDialog.showDialog(SparrowTerminal.get().getGui());
}); });
actions.addItem("Settings", () -> {
close();
SettingsDialog settingsDialog = getWalletData().getSettingsDialog();
settingsDialog.showDialog(SparrowTerminal.get().getGui());
});
Panel mainPanel = new Panel(); Panel mainPanel = new Panel();
mainPanel.setLayoutManager(new GridLayout(1).setLeftMarginSize(1).setRightMarginSize(1)); mainPanel.setLayoutManager(new GridLayout(1).setLeftMarginSize(1).setRightMarginSize(1));
@ -51,7 +56,7 @@ public class WalletActionsDialog extends DialogWindow {
Panel buttonPanel = new Panel(); Panel buttonPanel = new Panel();
buttonPanel.setLayoutManager(new GridLayout(2).setHorizontalSpacing(1)); buttonPanel.setLayoutManager(new GridLayout(2).setHorizontalSpacing(1));
Wallet masterWallet = wallet.isMasterWallet() ? wallet : wallet.getMasterWallet(); Wallet masterWallet = getWallet().isMasterWallet() ? getWallet() : getWallet().getMasterWallet();
if(masterWallet.getChildWallets().stream().anyMatch(childWallet -> !childWallet.isNested())) { if(masterWallet.getChildWallets().stream().anyMatch(childWallet -> !childWallet.isNested())) {
buttonPanel.addComponent(new Button("Accounts", this::onAccounts).setLayoutData(GridLayout.createLayoutData(GridLayout.Alignment.CENTER, GridLayout.Alignment.CENTER, true, false))); buttonPanel.addComponent(new Button("Accounts", this::onAccounts).setLayoutData(GridLayout.createLayoutData(GridLayout.Alignment.CENTER, GridLayout.Alignment.CENTER, true, false)));
} }
@ -80,17 +85,21 @@ public class WalletActionsDialog extends DialogWindow {
private void onAccounts() { private void onAccounts() {
close(); close();
WalletAccountsDialog walletAccountsDialog = new WalletAccountsDialog(wallet.isMasterWallet() ? wallet : wallet.getMasterWallet()); WalletAccountsDialog walletAccountsDialog = new WalletAccountsDialog(getWalletData().getWalletForm().getMasterWalletId());
walletAccountsDialog.setWalletAccount(wallet); walletAccountsDialog.setWalletAccount(getWallet());
walletAccountsDialog.showDialog(SparrowTerminal.get().getGui()); walletAccountsDialog.showDialog(SparrowTerminal.get().getGui());
} }
private WalletData getWalletData() { private WalletData getWalletData() {
WalletData walletData = SparrowTerminal.get().getWalletData().get(wallet); WalletData walletData = SparrowTerminal.get().getWalletData().get(walletId);
if(walletData == null) { if(walletData == null) {
throw new IllegalStateException("Wallet data is null for " + wallet.getFullDisplayName()); throw new IllegalStateException("Wallet data is null for " + walletId);
} }
return walletData; return walletData;
} }
private Wallet getWallet() {
return getWalletData().getWalletForm().getWallet();
}
} }

View file

@ -1,6 +1,7 @@
package com.sparrowwallet.sparrow.terminal.wallet; package com.sparrowwallet.sparrow.terminal.wallet;
import com.sparrowwallet.sparrow.EventManager; import com.sparrowwallet.sparrow.EventManager;
import com.sparrowwallet.sparrow.wallet.SettingsWalletForm;
import com.sparrowwallet.sparrow.wallet.WalletForm; import com.sparrowwallet.sparrow.wallet.WalletForm;
public class WalletData { public class WalletData {
@ -9,6 +10,7 @@ public class WalletData {
private ReceiveDialog receiveDialog; private ReceiveDialog receiveDialog;
private AddressesDialog addressesDialog; private AddressesDialog addressesDialog;
private UtxosDialog utxosDialog; private UtxosDialog utxosDialog;
private SettingsDialog settingsDialog;
public WalletData(WalletForm walletForm) { public WalletData(WalletForm walletForm) {
this.walletForm = walletForm; this.walletForm = walletForm;
@ -53,4 +55,14 @@ public class WalletData {
return utxosDialog; return utxosDialog;
} }
public SettingsDialog getSettingsDialog() {
if(settingsDialog == null) {
SettingsWalletForm settingsWalletForm = new SettingsWalletForm(walletForm.getStorage(), walletForm.getWallet());
settingsDialog = new SettingsDialog(settingsWalletForm);
EventManager.get().register(settingsDialog);
}
return settingsDialog;
}
} }

View file

@ -32,7 +32,7 @@ public class WalletDialog extends DialogWindow {
protected void onBack(Function function) { protected void onBack(Function function) {
close(); close();
WalletActionsDialog walletActionsDialog = new WalletActionsDialog(getWalletForm().getWallet()); WalletActionsDialog walletActionsDialog = new WalletActionsDialog(getWalletForm().getWalletId());
walletActionsDialog.setFunction(function); walletActionsDialog.setFunction(function);
walletActionsDialog.showDialog(SparrowTerminal.get().getGui()); walletActionsDialog.showDialog(SparrowTerminal.get().getGui());
} }