From f41203858c1f856918d8113c1d2bab2da4514c18 Mon Sep 17 00:00:00 2001 From: Christoph Atteneder Date: Fri, 3 Dec 2021 12:02:10 +0100 Subject: [PATCH] Add visual icon for duplicate offer functionality --- .../resources/i18n/displayStrings.properties | 1 + .../closedtrades/ClosedTradesView.fxml | 1 + .../closedtrades/ClosedTradesView.java | 80 +++++++++++++++---- .../portfolio/openoffer/OpenOffersView.fxml | 1 + .../portfolio/openoffer/OpenOffersView.java | 65 +++++++++++---- 5 files changed, 116 insertions(+), 32 deletions(-) diff --git a/core/src/main/resources/i18n/displayStrings.properties b/core/src/main/resources/i18n/displayStrings.properties index af7c8c5558..d4ab56438e 100644 --- a/core/src/main/resources/i18n/displayStrings.properties +++ b/core/src/main/resources/i18n/displayStrings.properties @@ -97,6 +97,7 @@ shared.BTCMinMax=BTC (min - max) shared.removeOffer=Remove offer shared.dontRemoveOffer=Don't remove offer shared.editOffer=Edit offer +shared.duplicateOffer=Duplicate offer shared.openLargeQRWindow=Open large QR code window shared.tradingAccount=Trading account shared.faq=Visit FAQ page diff --git a/desktop/src/main/java/bisq/desktop/main/portfolio/closedtrades/ClosedTradesView.fxml b/desktop/src/main/java/bisq/desktop/main/portfolio/closedtrades/ClosedTradesView.fxml index 5e0f1cd0f1..0bdd24821a 100644 --- a/desktop/src/main/java/bisq/desktop/main/portfolio/closedtrades/ClosedTradesView.fxml +++ b/desktop/src/main/java/bisq/desktop/main/portfolio/closedtrades/ClosedTradesView.fxml @@ -55,6 +55,7 @@ + diff --git a/desktop/src/main/java/bisq/desktop/main/portfolio/closedtrades/ClosedTradesView.java b/desktop/src/main/java/bisq/desktop/main/portfolio/closedtrades/ClosedTradesView.java index 9113fdc0ff..00200ad75b 100644 --- a/desktop/src/main/java/bisq/desktop/main/portfolio/closedtrades/ClosedTradesView.java +++ b/desktop/src/main/java/bisq/desktop/main/portfolio/closedtrades/ClosedTradesView.java @@ -60,11 +60,14 @@ import com.googlecode.jcsv.writer.CSVEntryConverter; import javax.inject.Inject; import javax.inject.Named; +import de.jensd.fx.glyphs.materialdesignicons.MaterialDesignIcon; + import javafx.fxml.FXML; import javafx.stage.Stage; import javafx.scene.Node; +import javafx.scene.control.Button; import javafx.scene.control.ContextMenu; import javafx.scene.control.Label; import javafx.scene.control.MenuItem; @@ -85,6 +88,8 @@ import javafx.beans.binding.Bindings; import javafx.beans.property.ReadOnlyObjectWrapper; import javafx.beans.value.ChangeListener; +import javafx.event.ActionEvent; + import javafx.collections.transformation.FilteredList; import javafx.collections.transformation.SortedList; @@ -94,6 +99,8 @@ import java.util.Comparator; import java.util.Date; import java.util.function.Function; +import static bisq.desktop.util.FormBuilder.getRegularIconButton; + @FxmlView public class ClosedTradesView extends ActivatableViewAndModel { private final boolean useDevPrivilegeKeys; @@ -132,7 +139,8 @@ public class ClosedTradesView extends ActivatableViewAndModel priceColumn, deviationColumn, amountColumn, volumeColumn, txFeeColumn, tradeFeeColumn, buyerSecurityDepositColumn, sellerSecurityDepositColumn, - marketColumn, directionColumn, dateColumn, tradeIdColumn, stateColumn, avatarColumn; + marketColumn, directionColumn, dateColumn, tradeIdColumn, stateColumn, + duplicateColumn, avatarColumn; @FXML HBox searchBox; @FXML @@ -198,6 +206,7 @@ public class ClosedTradesView extends ActivatableViewAndModel o.getId())); - dateColumn.setComparator(Comparator.comparing(o -> o.getDate())); + tradeIdColumn.setComparator(Comparator.comparing(Tradable::getId)); + dateColumn.setComparator(Comparator.comparing(Tradable::getDate)); directionColumn.setComparator(Comparator.comparing(o -> o.getOffer().getDirection())); marketColumn.setComparator(Comparator.comparing(model::getMarketLabel)); priceColumn.setComparator(Comparator.comparing(model::getPrice, Comparator.nullsFirst(Comparator.naturalOrder()))); @@ -229,7 +239,7 @@ public class ClosedTradesView extends ActivatableViewAndModel model.dataModel.getNumPastTrades(o), + model.dataModel::getNumPastTrades, Comparator.nullsFirst(Comparator.naturalOrder()) )); txFeeColumn.setComparator(nullsFirstComparing(o -> @@ -263,18 +273,7 @@ public class ClosedTradesView extends ActivatableViewAndModel row = new TableRow<>(); ContextMenu rowMenu = new ContextMenu(); MenuItem editItem = new MenuItem(Res.get("portfolio.context.offerLikeThis")); - editItem.setOnAction((event) -> { - try { - OfferPayloadBase offerPayloadBase = row.getItem().getOffer().getOfferPayloadBase(); - if (offerPayloadBase.getPubKeyRing().equals(keyRing.getPubKeyRing())) { - navigation.navigateToWithData(offerPayloadBase, MainView.class, PortfolioView.class, DuplicateOfferView.class); - } else { - new Popup().warning(Res.get("portfolio.context.notYourOffer")).show(); - } - } catch (NullPointerException e) { - log.warn("Unable to get offerPayload - {}", e.toString()); - } - }); + editItem.setOnAction((ActionEvent event) -> onDuplicateOffer(row.getItem().getOffer())); rowMenu.getItems().add(editItem); row.contextMenuProperty().bind( Bindings.when(Bindings.isNotNull(row.itemProperty())) @@ -579,6 +578,40 @@ public class ClosedTradesView extends ActivatableViewAndModel new ReadOnlyObjectWrapper<>(offerListItem.getValue())); + duplicateColumn.setCellFactory( + new Callback<>() { + @Override + public TableCell call(TableColumn column) { + return new TableCell<>() { + Button button; + + @Override + public void updateItem(final Tradable item, boolean empty) { + super.updateItem(item, empty); + + if (item != null && !empty) { + if (button == null) { + button = getRegularIconButton(MaterialDesignIcon.CONTENT_COPY); + button.setTooltip(new Tooltip(Res.get("shared.duplicateOffer"))); + setGraphic(button); + } + button.setOnAction(event -> onDuplicateOffer(item.getOffer())); + } else { + setGraphic(null); + if (button != null) { + button.setOnAction(null); + button = null; + } + } + } + }; + } + }); + } + @SuppressWarnings("UnusedReturnValue") private TableColumn setAvatarColumnCellFactory() { avatarColumn.getStyleClass().addAll("last-column", "avatar-column"); @@ -593,7 +626,7 @@ public class ClosedTradesView extends ActivatableViewAndModel + diff --git a/desktop/src/main/java/bisq/desktop/main/portfolio/openoffer/OpenOffersView.java b/desktop/src/main/java/bisq/desktop/main/portfolio/openoffer/OpenOffersView.java index 9afcea2a88..2020d6cb24 100644 --- a/desktop/src/main/java/bisq/desktop/main/portfolio/openoffer/OpenOffersView.java +++ b/desktop/src/main/java/bisq/desktop/main/portfolio/openoffer/OpenOffersView.java @@ -98,7 +98,7 @@ public class OpenOffersView extends ActivatableViewAndModel priceColumn, deviationColumn, amountColumn, volumeColumn, marketColumn, directionColumn, dateColumn, offerIdColumn, deactivateItemColumn, - removeItemColumn, editItemColumn, triggerPriceColumn, triggerIconColumn, paymentMethodColumn; + removeItemColumn, editItemColumn, triggerPriceColumn, triggerIconColumn, paymentMethodColumn, duplicateItemColumn; @FXML HBox searchBox; @FXML @@ -152,6 +152,7 @@ public class OpenOffersView extends ActivatableViewAndModel row = new TableRow<>(); final ContextMenu rowMenu = new ContextMenu(); MenuItem editItem = new MenuItem(Res.get("portfolio.context.offerLikeThis")); - editItem.setOnAction((event) -> { - try { - OfferPayloadBase offerPayloadBase = row.getItem().getOffer().getOfferPayloadBase(); - navigation.navigateToWithData(offerPayloadBase, MainView.class, PortfolioView.class, - DuplicateOfferView.class); - } catch (NullPointerException e) { - log.warn("Unable to get offerPayload - {}", e.toString()); - } - }); + editItem.setOnAction((event) -> onDuplicateOffer(row.getItem().getOffer())); rowMenu.getItems().add(editItem); row.contextMenuProperty().bind( Bindings.when(Bindings.isNotNull(row.itemProperty())) @@ -356,11 +350,8 @@ public class OpenOffersView extends ActivatableViewAndModel new ReadOnlyObjectWrapper<>(openOfferListItem.getValue())); offerIdColumn.getStyleClass().addAll("number-column", "first-column"); @@ -787,6 +788,40 @@ public class OpenOffersView extends ActivatableViewAndModel new ReadOnlyObjectWrapper<>(offerListItem.getValue())); + duplicateItemColumn.setCellFactory( + new Callback<>() { + @Override + public TableCell call(TableColumn column) { + return new TableCell<>() { + Button button; + + @Override + public void updateItem(final OpenOfferListItem item, boolean empty) { + super.updateItem(item, empty); + + if (item != null && !empty) { + if (button == null) { + button = getRegularIconButton(MaterialDesignIcon.CONTENT_COPY); + button.setTooltip(new Tooltip(Res.get("shared.duplicateOffer"))); + setGraphic(button); + } + button.setOnAction(event -> onDuplicateOffer(item.getOffer())); + } else { + setGraphic(null); + if (button != null) { + button.setOnAction(null); + button = null; + } + } + } + }; + } + }); + } + private void setTriggerIconColumnCellFactory() { triggerIconColumn.setCellValueFactory((offerListItem) -> new ReadOnlyObjectWrapper<>(offerListItem.getValue())); triggerIconColumn.setCellFactory(