From 1eb595823b08bc03f825a492a335122abb7cf17b Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Mon, 31 Jan 2022 19:14:50 +0200 Subject: [PATCH] search across all wallet accounts, reveal child items if selected --- drongo | 2 +- .../sparrowwallet/sparrow/AppController.java | 23 +++-- .../sparrow/control/SearchWalletDialog.java | 84 +++++++++++-------- .../sparrow/wallet/AddressesController.java | 2 +- .../sparrow/wallet/HashIndexEntry.java | 2 +- .../wallet/TransactionHashIndexEntry.java | 5 ++ .../wallet/TransactionsController.java | 2 +- .../sparrow/wallet/UtxosController.java | 2 +- .../sparrow/wallet/WalletFormController.java | 16 +++- 9 files changed, 85 insertions(+), 53 deletions(-) diff --git a/drongo b/drongo index 61317f15..9618c73c 160000 --- a/drongo +++ b/drongo @@ -1 +1 @@ -Subproject commit 61317f15ac795ef1a40c120d1e8aae2b2735c6ec +Subproject commit 9618c73c50e59035cd373d932970f446032cd9e5 diff --git a/src/main/java/com/sparrowwallet/sparrow/AppController.java b/src/main/java/com/sparrowwallet/sparrow/AppController.java index 520e25ef..3b2d3a99 100644 --- a/src/main/java/com/sparrowwallet/sparrow/AppController.java +++ b/src/main/java/com/sparrowwallet/sparrow/AppController.java @@ -1359,14 +1359,21 @@ public class AppController implements Initializable { } public void searchWallet(ActionEvent event) { - WalletForm selectedWalletForm = getSelectedWalletForm(); - if(selectedWalletForm != null) { - SearchWalletDialog searchWalletDialog = new SearchWalletDialog(selectedWalletForm); - Optional optEntry = searchWalletDialog.showAndWait(); - if(optEntry.isPresent()) { - Entry entry = optEntry.get(); - EventManager.get().post(new FunctionActionEvent(entry.getWalletFunction(), entry.getWallet())); - Platform.runLater(() -> EventManager.get().post(new SelectEntryEvent(entry))); + Tab selectedTab = tabs.getSelectionModel().getSelectedItem(); + if(selectedTab != null) { + TabData tabData = (TabData) selectedTab.getUserData(); + if(tabData instanceof WalletTabData) { + TabPane subTabs = (TabPane) selectedTab.getContent(); + List walletForms = subTabs.getTabs().stream().map(subTab -> ((WalletTabData)subTab.getUserData()).getWalletForm()).collect(Collectors.toList()); + if(!walletForms.isEmpty()) { + SearchWalletDialog searchWalletDialog = new SearchWalletDialog(walletForms); + Optional optEntry = searchWalletDialog.showAndWait(); + if(optEntry.isPresent()) { + Entry entry = optEntry.get(); + EventManager.get().post(new FunctionActionEvent(entry.getWalletFunction(), entry.getWallet())); + Platform.runLater(() -> EventManager.get().post(new SelectEntryEvent(entry))); + } + } } } } diff --git a/src/main/java/com/sparrowwallet/sparrow/control/SearchWalletDialog.java b/src/main/java/com/sparrowwallet/sparrow/control/SearchWalletDialog.java index 061a71a0..664db723 100644 --- a/src/main/java/com/sparrowwallet/sparrow/control/SearchWalletDialog.java +++ b/src/main/java/com/sparrowwallet/sparrow/control/SearchWalletDialog.java @@ -23,12 +23,16 @@ import java.util.List; public class SearchWalletDialog extends Dialog { private static final Logger log = LoggerFactory.getLogger(SearchWalletDialog.class); - private final WalletForm walletForm; + private final List walletForms; private final TextField search; private final CoinTreeTable results; - public SearchWalletDialog(WalletForm walletForm) { - this.walletForm = walletForm; + public SearchWalletDialog(List walletForms) { + this.walletForms = walletForms; + + if(walletForms.isEmpty()) { + throw new IllegalArgumentException("No wallets selected to search"); + } final DialogPane dialogPane = getDialogPane(); dialogPane.getStylesheets().add(AppServices.class.getResource("general.css").toExternalForm()); @@ -65,11 +69,19 @@ public class SearchWalletDialog extends Dialog { results = new CoinTreeTable(); results.setShowRoot(false); - results.setPrefWidth(850); - results.setBitcoinUnit(walletForm.getWallet()); + results.setPrefWidth(walletForms.size() > 1 ? 950 : 850); + results.setBitcoinUnit(walletForms.iterator().next().getWallet()); results.setColumnResizePolicy(TreeTableView.CONSTRAINED_RESIZE_POLICY); results.setPlaceholder(new Label("No results")); + if(walletForms.size() > 1) { + TreeTableColumn walletColumn = new TreeTableColumn<>("Wallet"); + walletColumn.setCellValueFactory((TreeTableColumn.CellDataFeatures param) -> { + return new ReadOnlyObjectWrapper<>(param.getValue().getValue().getWallet().getDisplayName()); + }); + results.getColumns().add(walletColumn); + } + TreeTableColumn typeColumn = new TreeTableColumn<>("Type"); typeColumn.setCellValueFactory((TreeTableColumn.CellDataFeatures param) -> { return new ReadOnlyObjectWrapper<>(param.getValue().getValue().getEntryType()); @@ -81,10 +93,8 @@ public class SearchWalletDialog extends Dialog { return new ReadOnlyObjectWrapper<>(param.getValue().getValue()); }); entryCol.setCellFactory(p -> new SearchEntryCell()); - String address = walletForm.getNodeEntry(KeyPurpose.RECEIVE).getAddress().toString(); - if(address != null) { - entryCol.setMinWidth(TextUtils.computeTextWidth(AppServices.getMonospaceFont(), address, 0.0)); - } + String address = walletForms.iterator().next().getNodeEntry(KeyPurpose.RECEIVE).getAddress().toString(); + entryCol.setMinWidth(TextUtils.computeTextWidth(AppServices.getMonospaceFont(), address, 0.0)); results.getColumns().add(entryCol); TreeTableColumn labelCol = new TreeTableColumn<>("Label"); @@ -138,43 +148,45 @@ public class SearchWalletDialog extends Dialog { //ignore } - WalletTransactionsEntry walletTransactionsEntry = walletForm.getWalletTransactionsEntry(); - for(Entry entry : walletTransactionsEntry.getChildren()) { - if(entry instanceof TransactionEntry transactionEntry) { - if(transactionEntry.getBlockTransaction().getHash().toString().equals(searchText) || - (transactionEntry.getLabel() != null && transactionEntry.getLabel().toLowerCase().contains(searchText)) || - (transactionEntry.getValue() != null && searchValue != null && Math.abs(transactionEntry.getValue()) == searchValue)) { - matchingEntries.add(entry); + for(WalletForm walletForm : walletForms) { + WalletTransactionsEntry walletTransactionsEntry = walletForm.getWalletTransactionsEntry(); + for(Entry entry : walletTransactionsEntry.getChildren()) { + if(entry instanceof TransactionEntry transactionEntry) { + if(transactionEntry.getBlockTransaction().getHash().toString().equals(searchText) || + (transactionEntry.getLabel() != null && transactionEntry.getLabel().toLowerCase().contains(searchText)) || + (transactionEntry.getValue() != null && searchValue != null && Math.abs(transactionEntry.getValue()) == searchValue)) { + matchingEntries.add(entry); + } } } - } - for(KeyPurpose keyPurpose : KeyPurpose.DEFAULT_PURPOSES) { - NodeEntry purposeEntry = walletForm.getNodeEntry(keyPurpose); - for(Entry entry : purposeEntry.getChildren()) { - if(entry instanceof NodeEntry nodeEntry) { - if(nodeEntry.getAddress().toString().contains(searchText) || - (nodeEntry.getLabel() != null && nodeEntry.getLabel().toLowerCase().contains(searchText)) || - (nodeEntry.getValue() != null && searchValue != null && Math.abs(nodeEntry.getValue()) == searchValue)) { + for(KeyPurpose keyPurpose : KeyPurpose.DEFAULT_PURPOSES) { + NodeEntry purposeEntry = walletForm.getNodeEntry(keyPurpose); + for(Entry entry : purposeEntry.getChildren()) { + if(entry instanceof NodeEntry nodeEntry) { + if(nodeEntry.getAddress().toString().contains(searchText) || + (nodeEntry.getLabel() != null && nodeEntry.getLabel().toLowerCase().contains(searchText)) || + (nodeEntry.getValue() != null && searchValue != null && Math.abs(nodeEntry.getValue()) == searchValue)) { + matchingEntries.add(entry); + } + } + } + } + + WalletUtxosEntry walletUtxosEntry = walletForm.getWalletUtxosEntry(); + for(Entry entry : walletUtxosEntry.getChildren()) { + if(entry instanceof HashIndexEntry hashIndexEntry) { + if(hashIndexEntry.getBlockTransaction().getHash().toString().equals(searchText) || + (hashIndexEntry.getLabel() != null && hashIndexEntry.getLabel().toLowerCase().contains(searchText)) || + (hashIndexEntry.getValue() != null && searchValue != null && Math.abs(hashIndexEntry.getValue()) == searchValue)) { matchingEntries.add(entry); } } } } - - WalletUtxosEntry walletUtxosEntry = walletForm.getWalletUtxosEntry(); - for(Entry entry : walletUtxosEntry.getChildren()) { - if(entry instanceof HashIndexEntry hashIndexEntry) { - if(hashIndexEntry.getBlockTransaction().getHash().toString().equals(searchText) || - (hashIndexEntry.getLabel() != null && hashIndexEntry.getLabel().toLowerCase().contains(searchText)) || - (hashIndexEntry.getValue() != null && searchValue != null && Math.abs(hashIndexEntry.getValue()) == searchValue)) { - matchingEntries.add(entry); - } - } - } } - SearchWalletEntry rootEntry = new SearchWalletEntry(walletForm.getWallet(), matchingEntries); + SearchWalletEntry rootEntry = new SearchWalletEntry(walletForms.iterator().next().getWallet(), matchingEntries); RecursiveTreeItem rootItem = new RecursiveTreeItem<>(rootEntry, Entry::getChildren); results.setRoot(rootItem); } diff --git a/src/main/java/com/sparrowwallet/sparrow/wallet/AddressesController.java b/src/main/java/com/sparrowwallet/sparrow/wallet/AddressesController.java index 12f38412..f8387305 100644 --- a/src/main/java/com/sparrowwallet/sparrow/wallet/AddressesController.java +++ b/src/main/java/com/sparrowwallet/sparrow/wallet/AddressesController.java @@ -105,7 +105,7 @@ public class AddressesController extends WalletFormController implements Initial if(event.getWallet().equals(getWalletForm().getWallet()) && event.getEntry().getWalletFunction() == Function.ADDRESSES) { List addressTreeTables = List.of(receiveTable, changeTable); for(AddressTreeTable addressTreeTable : addressTreeTables) { - selectEntry(addressTreeTable, event.getEntry()); + selectEntry(addressTreeTable, addressTreeTable.getRoot(), event.getEntry()); } } } diff --git a/src/main/java/com/sparrowwallet/sparrow/wallet/HashIndexEntry.java b/src/main/java/com/sparrowwallet/sparrow/wallet/HashIndexEntry.java index c6458969..c6444a5c 100644 --- a/src/main/java/com/sparrowwallet/sparrow/wallet/HashIndexEntry.java +++ b/src/main/java/com/sparrowwallet/sparrow/wallet/HashIndexEntry.java @@ -71,7 +71,7 @@ public class HashIndexEntry extends Entry implements Comparable @Override public String getEntryType() { - return "Hash Index"; + return type == Type.INPUT ? "Input" : "Output"; } @Override diff --git a/src/main/java/com/sparrowwallet/sparrow/wallet/TransactionHashIndexEntry.java b/src/main/java/com/sparrowwallet/sparrow/wallet/TransactionHashIndexEntry.java index bcce85e9..4cd2b766 100644 --- a/src/main/java/com/sparrowwallet/sparrow/wallet/TransactionHashIndexEntry.java +++ b/src/main/java/com/sparrowwallet/sparrow/wallet/TransactionHashIndexEntry.java @@ -33,4 +33,9 @@ public class TransactionHashIndexEntry extends HashIndexEntry { public boolean isSpent() { return false; } + + @Override + public Function getWalletFunction() { + return Function.TRANSACTIONS; + } } diff --git a/src/main/java/com/sparrowwallet/sparrow/wallet/TransactionsController.java b/src/main/java/com/sparrowwallet/sparrow/wallet/TransactionsController.java index a601c6ee..1baac343 100644 --- a/src/main/java/com/sparrowwallet/sparrow/wallet/TransactionsController.java +++ b/src/main/java/com/sparrowwallet/sparrow/wallet/TransactionsController.java @@ -281,7 +281,7 @@ public class TransactionsController extends WalletFormController implements Init @Subscribe public void selectEntry(SelectEntryEvent event) { if(event.getWallet().equals(getWalletForm().getWallet()) && event.getEntry().getWalletFunction() == Function.TRANSACTIONS) { - selectEntry(transactionsTable, event.getEntry()); + selectEntry(transactionsTable, transactionsTable.getRoot(), event.getEntry()); } } } diff --git a/src/main/java/com/sparrowwallet/sparrow/wallet/UtxosController.java b/src/main/java/com/sparrowwallet/sparrow/wallet/UtxosController.java index 39cc4b36..6ea14d28 100644 --- a/src/main/java/com/sparrowwallet/sparrow/wallet/UtxosController.java +++ b/src/main/java/com/sparrowwallet/sparrow/wallet/UtxosController.java @@ -609,7 +609,7 @@ public class UtxosController extends WalletFormController implements Initializab public void selectEntry(SelectEntryEvent event) { if(event.getWallet().equals(getWalletForm().getWallet()) && event.getEntry().getWalletFunction() == Function.UTXOS) { utxosTable.getSelectionModel().clearSelection(); - selectEntry(utxosTable, event.getEntry()); + selectEntry(utxosTable, utxosTable.getRoot(), event.getEntry()); } } } diff --git a/src/main/java/com/sparrowwallet/sparrow/wallet/WalletFormController.java b/src/main/java/com/sparrowwallet/sparrow/wallet/WalletFormController.java index c33f7f05..63f519ef 100644 --- a/src/main/java/com/sparrowwallet/sparrow/wallet/WalletFormController.java +++ b/src/main/java/com/sparrowwallet/sparrow/wallet/WalletFormController.java @@ -68,16 +68,24 @@ public abstract class WalletFormController extends BaseController { } } - protected void selectEntry(TreeTableView treeTableView, Entry entry) { - for(TreeItem treeEntry : treeTableView.getRoot().getChildren()) { + protected boolean selectEntry(TreeTableView treeTableView, TreeItem parentEntry, Entry entry) { + for(TreeItem treeEntry : parentEntry.getChildren()) { if(treeEntry.getValue().equals(entry)) { - treeTableView.getSelectionModel().select(treeEntry); Platform.runLater(() -> { treeTableView.requestFocus(); + treeTableView.getSelectionModel().select(treeEntry); treeTableView.scrollTo(treeTableView.getSelectionModel().getSelectedIndex()); }); - break; + return true; + } + + boolean selectedChild = selectEntry(treeTableView, treeEntry, entry); + if(selectedChild) { + treeEntry.setExpanded(true); + return true; } } + + return false; } }