keystore source quick chooser

This commit is contained in:
Craig Raw 2020-05-11 11:38:07 +02:00
parent 82a113afc3
commit 9241f4381f
10 changed files with 118 additions and 24 deletions

2
drongo

@ -1 +1 @@
Subproject commit 0f008b8985253c4fd0025c136d0a23ac3082537f Subproject commit c675e395dbbf386d2371ac3819b2a4539bf25e95

View file

@ -43,7 +43,7 @@ public class MainApp extends Application {
KeystoreImportDialog dlg = new KeystoreImportDialog(wallet); KeystoreImportDialog dlg = new KeystoreImportDialog(wallet);
dlg.showAndWait(); dlg.showAndWait();
// stage.show(); stage.show();
} }
public static void main(String[] args) { public static void main(String[] args) {

View file

@ -17,6 +17,7 @@ public class FontAwesome5 extends GlyphFont {
public static enum Glyph implements INamedCharacter { public static enum Glyph implements INamedCharacter {
CIRCLE('\uf111'), CIRCLE('\uf111'),
EXCLAMATION_CIRCLE('\uf06a'), EXCLAMATION_CIRCLE('\uf06a'),
EYE('\uf06e'),
LAPTOP('\uf109'), LAPTOP('\uf109'),
SD_CARD('\uf7c2'), SD_CARD('\uf7c2'),
WALLET('\uf555'); WALLET('\uf555');

View file

@ -4,10 +4,12 @@ import com.sparrowwallet.drongo.wallet.KeystoreSource;
import com.sparrowwallet.drongo.wallet.Wallet; import com.sparrowwallet.drongo.wallet.Wallet;
import com.sparrowwallet.sparrow.AppController; import com.sparrowwallet.sparrow.AppController;
import com.sparrowwallet.sparrow.io.Device; import com.sparrowwallet.sparrow.io.Device;
import javafx.application.Platform;
import javafx.fxml.FXML; import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader; import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable; import javafx.fxml.Initializable;
import javafx.scene.Node; import javafx.scene.Node;
import javafx.scene.control.Toggle;
import javafx.scene.control.ToggleGroup; import javafx.scene.control.ToggleGroup;
import javafx.scene.layout.StackPane; import javafx.scene.layout.StackPane;
@ -51,6 +53,15 @@ public class KeystoreImportController implements Initializable {
}); });
} }
public void selectSource(KeystoreSource keystoreSource) {
for(Toggle toggle : importMenu.getToggles()) {
if(toggle.getUserData().equals(keystoreSource)) {
Platform.runLater(() -> importMenu.selectToggle(toggle));
return;
}
}
}
void showUsbDevices(List<Device> devices) { void showUsbDevices(List<Device> devices) {
FXMLLoader loader = setImportPane("hw_usb-devices"); FXMLLoader loader = setImportPane("hw_usb-devices");
HwUsbDevicesController controller = loader.getController(); HwUsbDevicesController controller = loader.getController();

View file

@ -2,6 +2,7 @@ package com.sparrowwallet.sparrow.keystoreimport;
import com.google.common.eventbus.Subscribe; import com.google.common.eventbus.Subscribe;
import com.sparrowwallet.drongo.wallet.Keystore; import com.sparrowwallet.drongo.wallet.Keystore;
import com.sparrowwallet.drongo.wallet.KeystoreSource;
import com.sparrowwallet.drongo.wallet.Wallet; import com.sparrowwallet.drongo.wallet.Wallet;
import com.sparrowwallet.sparrow.AppController; import com.sparrowwallet.sparrow.AppController;
import com.sparrowwallet.sparrow.EventManager; import com.sparrowwallet.sparrow.EventManager;
@ -20,6 +21,10 @@ public class KeystoreImportDialog extends Dialog<Keystore> {
private Keystore keystore; private Keystore keystore;
public KeystoreImportDialog(Wallet wallet) { public KeystoreImportDialog(Wallet wallet) {
this(wallet, KeystoreSource.HW_USB);
}
public KeystoreImportDialog(Wallet wallet, KeystoreSource initialSource) {
EventManager.get().register(this); EventManager.get().register(this);
final DialogPane dialogPane = getDialogPane(); final DialogPane dialogPane = getDialogPane();
@ -28,6 +33,7 @@ public class KeystoreImportDialog extends Dialog<Keystore> {
dialogPane.setContent(Borders.wrap(ksiLoader.load()).lineBorder().outerPadding(0).innerPadding(0).buildAll()); dialogPane.setContent(Borders.wrap(ksiLoader.load()).lineBorder().outerPadding(0).innerPadding(0).buildAll());
keystoreImportController = ksiLoader.getController(); keystoreImportController = ksiLoader.getController();
keystoreImportController.initializeView(wallet); keystoreImportController.initializeView(wallet);
keystoreImportController.selectSource(initialSource);
final ButtonType cancelButtonType = new javafx.scene.control.ButtonType("Cancel", ButtonBar.ButtonData.CANCEL_CLOSE); final ButtonType cancelButtonType = new javafx.scene.control.ButtonType("Cancel", ButtonBar.ButtonData.CANCEL_CLOSE);
dialogPane.getButtonTypes().addAll(cancelButtonType); dialogPane.getButtonTypes().addAll(cancelButtonType);

View file

@ -12,14 +12,13 @@ import javafx.application.Platform;
import javafx.event.ActionEvent; import javafx.event.ActionEvent;
import javafx.fxml.FXML; import javafx.fxml.FXML;
import javafx.fxml.Initializable; import javafx.fxml.Initializable;
import javafx.scene.control.Control; import javafx.scene.control.*;
import javafx.scene.control.Label; import javafx.scene.layout.StackPane;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;
import org.controlsfx.validation.ValidationResult; import org.controlsfx.validation.ValidationResult;
import org.controlsfx.validation.ValidationSupport; import org.controlsfx.validation.ValidationSupport;
import org.controlsfx.validation.Validator; import org.controlsfx.validation.Validator;
import org.controlsfx.validation.decoration.StyleClassValidationDecoration; import org.controlsfx.validation.decoration.StyleClassValidationDecoration;
import tornadofx.control.Form;
import java.net.URL; import java.net.URL;
import java.util.Optional; import java.util.Optional;
@ -29,6 +28,9 @@ import java.util.stream.Collectors;
public class KeystoreController extends WalletFormController implements Initializable { public class KeystoreController extends WalletFormController implements Initializable {
private Keystore keystore; private Keystore keystore;
@FXML
private StackPane selectSourcePane;
@FXML @FXML
private Label type; private Label type;
@ -60,6 +62,8 @@ public class KeystoreController extends WalletFormController implements Initiali
public void initializeView() { public void initializeView() {
Platform.runLater(this::setupValidation); Platform.runLater(this::setupValidation);
selectSourcePane.managedProperty().bind(selectSourcePane.visibleProperty());
updateType(); updateType();
label.setText(keystore.getLabel()); label.setText(keystore.getLabel());
@ -97,6 +101,16 @@ public class KeystoreController extends WalletFormController implements Initiali
}); });
} }
public void selectSource(ActionEvent event) {
ToggleButton sourceButton = (ToggleButton)event.getSource();
KeystoreSource keystoreSource = (KeystoreSource)sourceButton.getUserData();
if(keystoreSource != KeystoreSource.SW_WATCH) {
launchImportDialog(keystoreSource);
} else {
selectSourcePane.setVisible(false);
}
}
public TextField getLabel() { public TextField getLabel() {
return label; return label;
} }
@ -150,14 +164,20 @@ public class KeystoreController extends WalletFormController implements Initiali
return "Software Wallet"; return "Software Wallet";
case SW_WATCH: case SW_WATCH:
default: default:
return "Software Wallet (Watch Only)"; return "Watch Only Wallet";
} }
} }
public void importKeystore(ActionEvent event) { public void importKeystore(ActionEvent event) {
KeystoreImportDialog dlg = new KeystoreImportDialog(getWalletForm().getWallet()); launchImportDialog(KeystoreSource.HW_USB);
}
private void launchImportDialog(KeystoreSource initialSource) {
KeystoreImportDialog dlg = new KeystoreImportDialog(getWalletForm().getWallet(), initialSource);
Optional<Keystore> result = dlg.showAndWait(); Optional<Keystore> result = dlg.showAndWait();
if (result.isPresent()) { if (result.isPresent()) {
selectSourcePane.setVisible(false);
Keystore importedKeystore = result.get(); Keystore importedKeystore = result.get();
keystore.setSource(importedKeystore.getSource()); keystore.setSource(importedKeystore.getSource());
keystore.setWalletModel(importedKeystore.getWalletModel()); keystore.setWalletModel(importedKeystore.getWalletModel());

View file

@ -47,6 +47,7 @@
.titled-pane > .title > .arrow-button > .arrow { .titled-pane > .title > .arrow-button > .arrow {
visibility: hidden; visibility: hidden;
-fx-translate-x: -1000; -fx-translate-x: -1000;
-fx-padding: 0;
} }
.main-label .text { .main-label .text {

View file

@ -26,7 +26,7 @@
<KeystoreSource fx:constant="HW_USB"/> <KeystoreSource fx:constant="HW_USB"/>
</userData> </userData>
</ToggleButton> </ToggleButton>
<ToggleButton VBox.vgrow="ALWAYS" text="Airgapped Wallet" wrapText="true" textAlignment="CENTER" contentDisplay="TOP" styleClass="list-item" maxHeight="Infinity" toggleGroup="$importMenu"> <ToggleButton VBox.vgrow="ALWAYS" text="Airgapped Hardware Wallet" wrapText="true" textAlignment="CENTER" contentDisplay="TOP" styleClass="list-item" maxHeight="Infinity" toggleGroup="$importMenu">
<graphic> <graphic>
<Glyph fontFamily="Font Awesome 5 Free Solid" fontSize="20" icon="SD_CARD" /> <Glyph fontFamily="Font Awesome 5 Free Solid" fontSize="20" icon="SD_CARD" />
</graphic> </graphic>

View file

@ -1,3 +1,14 @@
#selectSourcePane {
-fx-padding: 50 25 50 25;
-fx-background-color: -fx-background;
}
#selectSourcePane .toggle-button {
-fx-pref-height: 130px;
-fx-pref-width: 200px;
-fx-padding: 20px;
}
.form .fieldset:horizontal .label-container { .form .fieldset:horizontal .label-container {
-fx-pref-width: 140px; -fx-pref-width: 140px;
} }

View file

@ -10,11 +10,14 @@
<?import tornadofx.control.Field?> <?import tornadofx.control.Field?>
<?import javafx.geometry.Insets?> <?import javafx.geometry.Insets?>
<?import org.controlsfx.control.SegmentedButton?>
<?import com.sparrowwallet.drongo.wallet.KeystoreSource?>
<?import org.controlsfx.glyphfont.Glyph?>
<StackPane stylesheets="@keystore.css, @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.KeystoreController"> <StackPane stylesheets="@keystore.css, @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.KeystoreController">
<padding> <padding>
<Insets left="25.0" right="25.0" /> <Insets left="25.0" right="25.0" />
</padding> </padding>
<Form GridPane.columnIndex="0" GridPane.rowIndex="0"> <Form fx:id="keystoreForm" GridPane.columnIndex="0" GridPane.rowIndex="0">
<Fieldset inputGrow="SOMETIMES" text=""> <Fieldset inputGrow="SOMETIMES" text="">
<Field text="Type:"> <Field text="Type:">
<Label fx:id="type"/> <Label fx:id="type"/>
@ -35,4 +38,45 @@
</Field> </Field>
</Fieldset> </Fieldset>
</Form> </Form>
<StackPane fx:id="selectSourcePane">
<SegmentedButton>
<toggleGroup>
<ToggleGroup fx:id="keystoreSourceToggleGroup" />
</toggleGroup>
<buttons>
<ToggleButton text="Connected Hardware Wallet" contentDisplay="TOP" wrapText="true" textAlignment="CENTER" toggleGroup="$keystoreSourceToggleGroup" onAction="#selectSource">
<graphic>
<Glyph fontFamily="Font Awesome 5 Brands Regular" fontSize="20" icon="USB" />
</graphic>
<userData>
<KeystoreSource fx:constant="HW_USB"/>
</userData>
</ToggleButton>
<ToggleButton text="Airgapped Hardware Wallet" contentDisplay="TOP" wrapText="true" textAlignment="CENTER" toggleGroup="$keystoreSourceToggleGroup" onAction="#selectSource">
<graphic>
<Glyph fontFamily="Font Awesome 5 Free Solid" fontSize="20" icon="SD_CARD" />
</graphic>
<userData>
<KeystoreSource fx:constant="HW_AIRGAPPED"/>
</userData>
</ToggleButton>
<ToggleButton text="New or Imported Software Wallet" contentDisplay="TOP" wrapText="true" textAlignment="CENTER" toggleGroup="$keystoreSourceToggleGroup" onAction="#selectSource">
<graphic>
<Glyph fontFamily="Font Awesome 5 Free Solid" fontSize="20" icon="LAPTOP" />
</graphic>
<userData>
<KeystoreSource fx:constant="SW_SEED"/>
</userData>
</ToggleButton>
<ToggleButton text="XPUB / Watch Only Wallet" contentDisplay="TOP" wrapText="true" textAlignment="CENTER" toggleGroup="$keystoreSourceToggleGroup" onAction="#selectSource">
<graphic>
<Glyph fontFamily="Font Awesome 5 Free Solid" fontSize="20" icon="EYE" />
</graphic>
<userData>
<KeystoreSource fx:constant="SW_WATCH"/>
</userData>
</ToggleButton>
</buttons>
</SegmentedButton>
</StackPane>
</StackPane> </StackPane>