mirror of
https://github.com/sparrowwallet/sparrow.git
synced 2024-12-24 12:46:45 +00:00
search across all wallet accounts, reveal child items if selected
This commit is contained in:
parent
6d2167428f
commit
1eb595823b
9 changed files with 85 additions and 53 deletions
2
drongo
2
drongo
|
@ -1 +1 @@
|
||||||
Subproject commit 61317f15ac795ef1a40c120d1e8aae2b2735c6ec
|
Subproject commit 9618c73c50e59035cd373d932970f446032cd9e5
|
|
@ -1359,14 +1359,21 @@ public class AppController implements Initializable {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void searchWallet(ActionEvent event) {
|
public void searchWallet(ActionEvent event) {
|
||||||
WalletForm selectedWalletForm = getSelectedWalletForm();
|
Tab selectedTab = tabs.getSelectionModel().getSelectedItem();
|
||||||
if(selectedWalletForm != null) {
|
if(selectedTab != null) {
|
||||||
SearchWalletDialog searchWalletDialog = new SearchWalletDialog(selectedWalletForm);
|
TabData tabData = (TabData) selectedTab.getUserData();
|
||||||
Optional<Entry> optEntry = searchWalletDialog.showAndWait();
|
if(tabData instanceof WalletTabData) {
|
||||||
if(optEntry.isPresent()) {
|
TabPane subTabs = (TabPane) selectedTab.getContent();
|
||||||
Entry entry = optEntry.get();
|
List<WalletForm> walletForms = subTabs.getTabs().stream().map(subTab -> ((WalletTabData)subTab.getUserData()).getWalletForm()).collect(Collectors.toList());
|
||||||
EventManager.get().post(new FunctionActionEvent(entry.getWalletFunction(), entry.getWallet()));
|
if(!walletForms.isEmpty()) {
|
||||||
Platform.runLater(() -> EventManager.get().post(new SelectEntryEvent(entry)));
|
SearchWalletDialog searchWalletDialog = new SearchWalletDialog(walletForms);
|
||||||
|
Optional<Entry> 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)));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,12 +23,16 @@ import java.util.List;
|
||||||
public class SearchWalletDialog extends Dialog<Entry> {
|
public class SearchWalletDialog extends Dialog<Entry> {
|
||||||
private static final Logger log = LoggerFactory.getLogger(SearchWalletDialog.class);
|
private static final Logger log = LoggerFactory.getLogger(SearchWalletDialog.class);
|
||||||
|
|
||||||
private final WalletForm walletForm;
|
private final List<WalletForm> walletForms;
|
||||||
private final TextField search;
|
private final TextField search;
|
||||||
private final CoinTreeTable results;
|
private final CoinTreeTable results;
|
||||||
|
|
||||||
public SearchWalletDialog(WalletForm walletForm) {
|
public SearchWalletDialog(List<WalletForm> walletForms) {
|
||||||
this.walletForm = walletForm;
|
this.walletForms = walletForms;
|
||||||
|
|
||||||
|
if(walletForms.isEmpty()) {
|
||||||
|
throw new IllegalArgumentException("No wallets selected to search");
|
||||||
|
}
|
||||||
|
|
||||||
final DialogPane dialogPane = getDialogPane();
|
final DialogPane dialogPane = getDialogPane();
|
||||||
dialogPane.getStylesheets().add(AppServices.class.getResource("general.css").toExternalForm());
|
dialogPane.getStylesheets().add(AppServices.class.getResource("general.css").toExternalForm());
|
||||||
|
@ -65,11 +69,19 @@ public class SearchWalletDialog extends Dialog<Entry> {
|
||||||
|
|
||||||
results = new CoinTreeTable();
|
results = new CoinTreeTable();
|
||||||
results.setShowRoot(false);
|
results.setShowRoot(false);
|
||||||
results.setPrefWidth(850);
|
results.setPrefWidth(walletForms.size() > 1 ? 950 : 850);
|
||||||
results.setBitcoinUnit(walletForm.getWallet());
|
results.setBitcoinUnit(walletForms.iterator().next().getWallet());
|
||||||
results.setColumnResizePolicy(TreeTableView.CONSTRAINED_RESIZE_POLICY);
|
results.setColumnResizePolicy(TreeTableView.CONSTRAINED_RESIZE_POLICY);
|
||||||
results.setPlaceholder(new Label("No results"));
|
results.setPlaceholder(new Label("No results"));
|
||||||
|
|
||||||
|
if(walletForms.size() > 1) {
|
||||||
|
TreeTableColumn<Entry, String> walletColumn = new TreeTableColumn<>("Wallet");
|
||||||
|
walletColumn.setCellValueFactory((TreeTableColumn.CellDataFeatures<Entry, String> param) -> {
|
||||||
|
return new ReadOnlyObjectWrapper<>(param.getValue().getValue().getWallet().getDisplayName());
|
||||||
|
});
|
||||||
|
results.getColumns().add(walletColumn);
|
||||||
|
}
|
||||||
|
|
||||||
TreeTableColumn<Entry, String> typeColumn = new TreeTableColumn<>("Type");
|
TreeTableColumn<Entry, String> typeColumn = new TreeTableColumn<>("Type");
|
||||||
typeColumn.setCellValueFactory((TreeTableColumn.CellDataFeatures<Entry, String> param) -> {
|
typeColumn.setCellValueFactory((TreeTableColumn.CellDataFeatures<Entry, String> param) -> {
|
||||||
return new ReadOnlyObjectWrapper<>(param.getValue().getValue().getEntryType());
|
return new ReadOnlyObjectWrapper<>(param.getValue().getValue().getEntryType());
|
||||||
|
@ -81,10 +93,8 @@ public class SearchWalletDialog extends Dialog<Entry> {
|
||||||
return new ReadOnlyObjectWrapper<>(param.getValue().getValue());
|
return new ReadOnlyObjectWrapper<>(param.getValue().getValue());
|
||||||
});
|
});
|
||||||
entryCol.setCellFactory(p -> new SearchEntryCell());
|
entryCol.setCellFactory(p -> new SearchEntryCell());
|
||||||
String address = walletForm.getNodeEntry(KeyPurpose.RECEIVE).getAddress().toString();
|
String address = walletForms.iterator().next().getNodeEntry(KeyPurpose.RECEIVE).getAddress().toString();
|
||||||
if(address != null) {
|
entryCol.setMinWidth(TextUtils.computeTextWidth(AppServices.getMonospaceFont(), address, 0.0));
|
||||||
entryCol.setMinWidth(TextUtils.computeTextWidth(AppServices.getMonospaceFont(), address, 0.0));
|
|
||||||
}
|
|
||||||
results.getColumns().add(entryCol);
|
results.getColumns().add(entryCol);
|
||||||
|
|
||||||
TreeTableColumn<Entry, String> labelCol = new TreeTableColumn<>("Label");
|
TreeTableColumn<Entry, String> labelCol = new TreeTableColumn<>("Label");
|
||||||
|
@ -138,43 +148,45 @@ public class SearchWalletDialog extends Dialog<Entry> {
|
||||||
//ignore
|
//ignore
|
||||||
}
|
}
|
||||||
|
|
||||||
WalletTransactionsEntry walletTransactionsEntry = walletForm.getWalletTransactionsEntry();
|
for(WalletForm walletForm : walletForms) {
|
||||||
for(Entry entry : walletTransactionsEntry.getChildren()) {
|
WalletTransactionsEntry walletTransactionsEntry = walletForm.getWalletTransactionsEntry();
|
||||||
if(entry instanceof TransactionEntry transactionEntry) {
|
for(Entry entry : walletTransactionsEntry.getChildren()) {
|
||||||
if(transactionEntry.getBlockTransaction().getHash().toString().equals(searchText) ||
|
if(entry instanceof TransactionEntry transactionEntry) {
|
||||||
(transactionEntry.getLabel() != null && transactionEntry.getLabel().toLowerCase().contains(searchText)) ||
|
if(transactionEntry.getBlockTransaction().getHash().toString().equals(searchText) ||
|
||||||
(transactionEntry.getValue() != null && searchValue != null && Math.abs(transactionEntry.getValue()) == searchValue)) {
|
(transactionEntry.getLabel() != null && transactionEntry.getLabel().toLowerCase().contains(searchText)) ||
|
||||||
matchingEntries.add(entry);
|
(transactionEntry.getValue() != null && searchValue != null && Math.abs(transactionEntry.getValue()) == searchValue)) {
|
||||||
|
matchingEntries.add(entry);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
for(KeyPurpose keyPurpose : KeyPurpose.DEFAULT_PURPOSES) {
|
for(KeyPurpose keyPurpose : KeyPurpose.DEFAULT_PURPOSES) {
|
||||||
NodeEntry purposeEntry = walletForm.getNodeEntry(keyPurpose);
|
NodeEntry purposeEntry = walletForm.getNodeEntry(keyPurpose);
|
||||||
for(Entry entry : purposeEntry.getChildren()) {
|
for(Entry entry : purposeEntry.getChildren()) {
|
||||||
if(entry instanceof NodeEntry nodeEntry) {
|
if(entry instanceof NodeEntry nodeEntry) {
|
||||||
if(nodeEntry.getAddress().toString().contains(searchText) ||
|
if(nodeEntry.getAddress().toString().contains(searchText) ||
|
||||||
(nodeEntry.getLabel() != null && nodeEntry.getLabel().toLowerCase().contains(searchText)) ||
|
(nodeEntry.getLabel() != null && nodeEntry.getLabel().toLowerCase().contains(searchText)) ||
|
||||||
(nodeEntry.getValue() != null && searchValue != null && Math.abs(nodeEntry.getValue()) == searchValue)) {
|
(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);
|
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<Entry> rootItem = new RecursiveTreeItem<>(rootEntry, Entry::getChildren);
|
RecursiveTreeItem<Entry> rootItem = new RecursiveTreeItem<>(rootEntry, Entry::getChildren);
|
||||||
results.setRoot(rootItem);
|
results.setRoot(rootItem);
|
||||||
}
|
}
|
||||||
|
|
|
@ -105,7 +105,7 @@ public class AddressesController extends WalletFormController implements Initial
|
||||||
if(event.getWallet().equals(getWalletForm().getWallet()) && event.getEntry().getWalletFunction() == Function.ADDRESSES) {
|
if(event.getWallet().equals(getWalletForm().getWallet()) && event.getEntry().getWalletFunction() == Function.ADDRESSES) {
|
||||||
List<AddressTreeTable> addressTreeTables = List.of(receiveTable, changeTable);
|
List<AddressTreeTable> addressTreeTables = List.of(receiveTable, changeTable);
|
||||||
for(AddressTreeTable addressTreeTable : addressTreeTables) {
|
for(AddressTreeTable addressTreeTable : addressTreeTables) {
|
||||||
selectEntry(addressTreeTable, event.getEntry());
|
selectEntry(addressTreeTable, addressTreeTable.getRoot(), event.getEntry());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,7 +71,7 @@ public class HashIndexEntry extends Entry implements Comparable<HashIndexEntry>
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getEntryType() {
|
public String getEntryType() {
|
||||||
return "Hash Index";
|
return type == Type.INPUT ? "Input" : "Output";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -33,4 +33,9 @@ public class TransactionHashIndexEntry extends HashIndexEntry {
|
||||||
public boolean isSpent() {
|
public boolean isSpent() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Function getWalletFunction() {
|
||||||
|
return Function.TRANSACTIONS;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -281,7 +281,7 @@ public class TransactionsController extends WalletFormController implements Init
|
||||||
@Subscribe
|
@Subscribe
|
||||||
public void selectEntry(SelectEntryEvent event) {
|
public void selectEntry(SelectEntryEvent event) {
|
||||||
if(event.getWallet().equals(getWalletForm().getWallet()) && event.getEntry().getWalletFunction() == Function.TRANSACTIONS) {
|
if(event.getWallet().equals(getWalletForm().getWallet()) && event.getEntry().getWalletFunction() == Function.TRANSACTIONS) {
|
||||||
selectEntry(transactionsTable, event.getEntry());
|
selectEntry(transactionsTable, transactionsTable.getRoot(), event.getEntry());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -609,7 +609,7 @@ public class UtxosController extends WalletFormController implements Initializab
|
||||||
public void selectEntry(SelectEntryEvent event) {
|
public void selectEntry(SelectEntryEvent event) {
|
||||||
if(event.getWallet().equals(getWalletForm().getWallet()) && event.getEntry().getWalletFunction() == Function.UTXOS) {
|
if(event.getWallet().equals(getWalletForm().getWallet()) && event.getEntry().getWalletFunction() == Function.UTXOS) {
|
||||||
utxosTable.getSelectionModel().clearSelection();
|
utxosTable.getSelectionModel().clearSelection();
|
||||||
selectEntry(utxosTable, event.getEntry());
|
selectEntry(utxosTable, utxosTable.getRoot(), event.getEntry());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,16 +68,24 @@ public abstract class WalletFormController extends BaseController {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void selectEntry(TreeTableView<Entry> treeTableView, Entry entry) {
|
protected boolean selectEntry(TreeTableView<Entry> treeTableView, TreeItem<Entry> parentEntry, Entry entry) {
|
||||||
for(TreeItem<Entry> treeEntry : treeTableView.getRoot().getChildren()) {
|
for(TreeItem<Entry> treeEntry : parentEntry.getChildren()) {
|
||||||
if(treeEntry.getValue().equals(entry)) {
|
if(treeEntry.getValue().equals(entry)) {
|
||||||
treeTableView.getSelectionModel().select(treeEntry);
|
|
||||||
Platform.runLater(() -> {
|
Platform.runLater(() -> {
|
||||||
treeTableView.requestFocus();
|
treeTableView.requestFocus();
|
||||||
|
treeTableView.getSelectionModel().select(treeEntry);
|
||||||
treeTableView.scrollTo(treeTableView.getSelectionModel().getSelectedIndex());
|
treeTableView.scrollTo(treeTableView.getSelectionModel().getSelectedIndex());
|
||||||
});
|
});
|
||||||
break;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean selectedChild = selectEntry(treeTableView, treeEntry, entry);
|
||||||
|
if(selectedChild) {
|
||||||
|
treeEntry.setExpanded(true);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue