diff --git a/src/main/java/com/sparrowwallet/sparrow/control/MnemonicGridDialog.java b/src/main/java/com/sparrowwallet/sparrow/control/MnemonicGridDialog.java index b3338f2c..9ba7339a 100644 --- a/src/main/java/com/sparrowwallet/sparrow/control/MnemonicGridDialog.java +++ b/src/main/java/com/sparrowwallet/sparrow/control/MnemonicGridDialog.java @@ -10,22 +10,20 @@ import javafx.beans.property.SimpleBooleanProperty; import javafx.collections.FXCollections; import javafx.collections.ListChangeListener; import javafx.collections.ObservableList; -import javafx.event.Event; import javafx.scene.Node; import javafx.scene.control.*; import javafx.scene.image.Image; import javafx.scene.image.ImageView; -import javafx.scene.input.MouseEvent; import javafx.scene.layout.StackPane; +import javafx.scene.text.Font; +import javafx.scene.text.Text; import javafx.stage.FileChooser; import org.controlsfx.control.spreadsheet.*; import org.controlsfx.glyphfont.Glyph; -import org.controlsfx.tools.Platform; import java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; -import java.lang.reflect.Field; import java.util.ArrayList; import java.util.List; import java.util.Optional; @@ -41,7 +39,7 @@ public class MnemonicGridDialog extends Dialog> { private final BooleanProperty initializedProperty = new SimpleBooleanProperty(false); private final BooleanProperty wordsSelectedProperty = new SimpleBooleanProperty(false); - private final List selectedCells = new ArrayList<>(); + private final ObservableList selectedCells = FXCollections.observableArrayList(); public MnemonicGridDialog() { DialogPane dialogPane = new MnemonicGridDialogPane(); @@ -49,7 +47,7 @@ public class MnemonicGridDialog extends Dialog> { setTitle("Border Wallets Grid"); dialogPane.getStylesheets().add(AppServices.class.getResource("general.css").toExternalForm()); dialogPane.getStylesheets().add(AppServices.class.getResource("grid.css").toExternalForm()); - dialogPane.setHeaderText("Load a Border Wallets PDF, or generate a grid from a BIP39 seed.\nThen select 11 or 23 words in a pattern on the grid, one at a time (do not drag).\nThe order of selection is important!"); + dialogPane.setHeaderText("Load a Border Wallets PDF, or generate a grid from a BIP39 seed.\nThen select 11 or 23 words in a pattern on the grid.\nThe order of selection is important!"); javafx.scene.image.Image image = new Image("/image/border-wallets.png"); dialogPane.setGraphic(new ImageView(image)); @@ -57,37 +55,56 @@ public class MnemonicGridDialog extends Dialog> { Grid grid = getGrid(emptyWordGrid); spreadsheetView = new SpreadsheetView(grid); - spreadsheetView.addEventFilter(MouseEvent.MOUSE_PRESSED, event -> { - try { - Field f = event.getClass().getDeclaredField(Platform.getCurrent() == Platform.OSX ? "metaDown" : "controlDown"); - f.setAccessible(true); - f.set(event, true); - } catch(IllegalAccessException | NoSuchFieldException e) { - //ignore - } - }); spreadsheetView.setId("grid"); spreadsheetView.setEditable(false); spreadsheetView.setFixingColumnsAllowed(false); spreadsheetView.setFixingRowsAllowed(false); + spreadsheetView.getSelectionModel().setSelectionMode(SelectionMode.SINGLE); spreadsheetView.getSelectionModel().getSelectedCells().addListener(new ListChangeListener<>() { @Override public void onChanged(Change c) { while(c.next()) { - if(c.wasRemoved()) { - selectedCells.removeAll(c.getRemoved()); - } if(c.wasAdded()) { - selectedCells.addAll(c.getAddedSubList()); + for(TablePosition pos : c.getAddedSubList()) { + if(selectedCells.contains(pos)) { + selectedCells.remove(pos); + } else { + selectedCells.add(pos); + } + } } } - int numWords = c.getList().size(); + int numWords = selectedCells.size(); wordsSelectedProperty.set(numWords == 11 || numWords == 23); } }); + selectedCells.addListener((ListChangeListener) c -> { + while(c.next()) { + if(c.wasRemoved()) { + for(TablePosition pos : c.getRemoved()) { + SpreadsheetCell cell = spreadsheetView.getGrid().getRows().get(pos.getRow()).get(pos.getColumn()); + cell.getStyleClass().remove("selection"); + cell.setGraphic(null); + } + } + if(c.wasAdded()) { + for(TablePosition pos : c.getAddedSubList()) { + SpreadsheetCell cell = spreadsheetView.getGrid().getRows().get(pos.getRow()).get(pos.getColumn()); + cell.getStyleClass().add("selection"); + } + } + for(int i = 0; i < selectedCells.size(); i++) { + Text index = new Text(Integer.toString(i+1)); + index.setFont(Font.font(8)); + SpreadsheetCell cell = spreadsheetView.getGrid().getRows().get(selectedCells.get(i).getRow()).get(selectedCells.get(i).getColumn()); + cell.setGraphic(index); + } + } + }); + StackPane stackPane = new StackPane(); stackPane.getChildren().add(spreadsheetView); dialogPane.setContent(stackPane); diff --git a/src/main/java/com/sparrowwallet/sparrow/io/PdfUtils.java b/src/main/java/com/sparrowwallet/sparrow/io/PdfUtils.java index af33a0d3..ecdecdce 100644 --- a/src/main/java/com/sparrowwallet/sparrow/io/PdfUtils.java +++ b/src/main/java/com/sparrowwallet/sparrow/io/PdfUtils.java @@ -157,7 +157,7 @@ public class PdfUtils { Font headerFont = new Font(Font.HELVETICA, 8, Font.BOLD, Color.DARK_GRAY); Font font = new Font(Font.HELVETICA, 8, Font.NORMAL, Color.DARK_GRAY); - HeaderFooter footer = new HeaderFooter(false, new Phrase("Recovery Phrase: " + String.join(" ", mnemonicWords), font)); + HeaderFooter footer = new HeaderFooter(false, new Phrase("Recovery Phrase (to regenerate grid): " + String.join(" ", mnemonicWords), font)); footer.setAlignment(Element.ALIGN_CENTER); footer.setBorder(Rectangle.NO_BORDER); footer.setBorderWidth(0); diff --git a/src/main/resources/com/sparrowwallet/sparrow/grid.css b/src/main/resources/com/sparrowwallet/sparrow/grid.css index 58fb44b8..8258e645 100644 --- a/src/main/resources/com/sparrowwallet/sparrow/grid.css +++ b/src/main/resources/com/sparrowwallet/sparrow/grid.css @@ -1,5 +1,13 @@ #grid .spreadsheet-cell:selected, #grid .spreadsheet-cell:focused:selected, #grid .spreadsheet-cell:focused:selected:hover { + -fx-background-color: transparent; +} + +#grid .spreadsheet-cell.selection:selected, +#grid .spreadsheet-cell.selection:focused:selected, +#grid .spreadsheet-cell.selection:focused:selected:hover, +#grid .spreadsheet-cell.selection { -fx-background-color: rgb(238, 210, 2); + -fx-content-display: RIGHT; } \ No newline at end of file