mirror of
https://github.com/bisq-network/bisq.git
synced 2025-02-24 23:18:17 +01:00
Add num items text field below tables
Move filter in history to top, fix wrong label Add export to cvs to reserved and locked balances
This commit is contained in:
parent
bc1f6ddac5
commit
d3b68bf9e6
18 changed files with 441 additions and 115 deletions
|
@ -219,7 +219,8 @@ shared.refundAgentForSupportStaff=Refund agent
|
|||
shared.delayedPayoutTxId=Delayed payout transaction ID
|
||||
shared.delayedPayoutTxReceiverAddress=Delayed payout transaction sent to
|
||||
shared.unconfirmedTransactionsLimitReached=You have too many unconfirmed transactions at the moment. Please try again later.
|
||||
|
||||
shared.numItemsLabel=Number of entries: {0}
|
||||
shared.filter=Filter
|
||||
|
||||
####################################################################
|
||||
# UI views
|
||||
|
@ -1053,7 +1054,6 @@ funds.tx.dustAttackTx.popup=This transaction is sending a very small BTC amount
|
|||
To protect your privacy the Bisq wallet ignores such dust outputs for spending purposes and in the balance display. \
|
||||
You can set the threshold amount when an output is considered dust in the settings.
|
||||
|
||||
|
||||
####################################################################
|
||||
# Support
|
||||
####################################################################
|
||||
|
|
|
@ -18,12 +18,13 @@
|
|||
package bisq.desktop.main.funds.locked;
|
||||
|
||||
import bisq.desktop.components.AutoTooltipLabel;
|
||||
import bisq.desktop.util.DisplayUtils;
|
||||
|
||||
import bisq.core.btc.listeners.BalanceListener;
|
||||
import bisq.core.btc.model.AddressEntry;
|
||||
import bisq.core.btc.wallet.BtcWalletService;
|
||||
import bisq.core.btc.wallet.WalletService;
|
||||
import bisq.core.trade.Tradable;
|
||||
import bisq.core.locale.Res;
|
||||
import bisq.core.trade.Trade;
|
||||
import bisq.core.util.coin.CoinFormatter;
|
||||
|
||||
|
@ -33,21 +34,34 @@ import org.bitcoinj.core.Transaction;
|
|||
|
||||
import javafx.scene.control.Label;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
class LockedListItem {
|
||||
private final BalanceListener balanceListener;
|
||||
private final Label balanceLabel;
|
||||
private final Trade trade;
|
||||
private final AddressEntry addressEntry;
|
||||
private final BtcWalletService btcWalletService;
|
||||
private final CoinFormatter formatter;
|
||||
|
||||
@Getter
|
||||
private final Label balanceLabel;
|
||||
@Getter
|
||||
private final Trade trade;
|
||||
@Getter
|
||||
private final AddressEntry addressEntry;
|
||||
@Getter
|
||||
private final String addressString;
|
||||
@Nullable
|
||||
private final Address address;
|
||||
@Getter
|
||||
private Coin balance;
|
||||
@Getter
|
||||
private String balanceString;
|
||||
|
||||
public LockedListItem(Trade trade, AddressEntry addressEntry, BtcWalletService btcWalletService, CoinFormatter formatter) {
|
||||
public LockedListItem(Trade trade,
|
||||
AddressEntry addressEntry,
|
||||
BtcWalletService btcWalletService,
|
||||
CoinFormatter formatter) {
|
||||
this.trade = trade;
|
||||
this.addressEntry = addressEntry;
|
||||
this.btcWalletService = btcWalletService;
|
||||
|
@ -55,15 +69,13 @@ class LockedListItem {
|
|||
|
||||
if (trade.getDepositTx() != null && !trade.getDepositTx().getOutputs().isEmpty()) {
|
||||
address = WalletService.getAddressFromOutput(trade.getDepositTx().getOutput(0));
|
||||
addressString = address.toString();
|
||||
addressString = address != null ? address.toString() : "";
|
||||
} else {
|
||||
address = null;
|
||||
addressString = "";
|
||||
}
|
||||
|
||||
// balance
|
||||
balanceLabel = new AutoTooltipLabel();
|
||||
balanceListener = new BalanceListener(getAddress()) {
|
||||
balanceListener = new BalanceListener(address) {
|
||||
@Override
|
||||
public void onBalanceChanged(Coin balance, Transaction tx) {
|
||||
updateBalance();
|
||||
|
@ -73,38 +85,36 @@ class LockedListItem {
|
|||
updateBalance();
|
||||
}
|
||||
|
||||
LockedListItem() {
|
||||
this.trade = null;
|
||||
this.addressEntry = null;
|
||||
this.btcWalletService = null;
|
||||
this.formatter = null;
|
||||
addressString = null;
|
||||
address = null;
|
||||
balanceLabel = null;
|
||||
balanceListener = null;
|
||||
}
|
||||
|
||||
public void cleanup() {
|
||||
btcWalletService.removeBalanceListener(balanceListener);
|
||||
}
|
||||
|
||||
private void updateBalance() {
|
||||
balance = addressEntry.getCoinLockedInMultiSigAsCoin();
|
||||
balanceLabel.setText(formatter.formatCoin(this.balance));
|
||||
balanceString = formatter.formatCoin(this.balance);
|
||||
balanceLabel.setText(balanceString);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private Address getAddress() {
|
||||
return address;
|
||||
public String getDetails() {
|
||||
return trade != null ?
|
||||
Res.get("funds.locked.locked", trade.getShortId()) :
|
||||
Res.get("shared.noDetailsAvailable");
|
||||
}
|
||||
|
||||
public AddressEntry getAddressEntry() {
|
||||
return addressEntry;
|
||||
public String getDateString() {
|
||||
return trade != null ?
|
||||
DisplayUtils.formatDateTime(trade.getDate()) :
|
||||
Res.get("shared.noDateAvailable");
|
||||
}
|
||||
|
||||
public Label getBalanceLabel() {
|
||||
return balanceLabel;
|
||||
}
|
||||
|
||||
public Coin getBalance() {
|
||||
return balance;
|
||||
}
|
||||
|
||||
public String getAddressString() {
|
||||
return addressString;
|
||||
}
|
||||
|
||||
public Tradable getTrade() {
|
||||
return trade;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -17,8 +17,12 @@
|
|||
~ along with Bisq. If not, see <http://www.gnu.org/licenses/>.
|
||||
-->
|
||||
|
||||
<?import bisq.desktop.components.AutoTooltipButton?>
|
||||
<?import javafx.scene.control.Label?>
|
||||
<?import javafx.scene.control.TableColumn?>
|
||||
<?import javafx.scene.control.TableView?>
|
||||
<?import javafx.scene.layout.HBox?>
|
||||
<?import javafx.scene.layout.Region?>
|
||||
<?import javafx.scene.layout.VBox?>
|
||||
<?import javafx.geometry.Insets?>
|
||||
<VBox fx:id="root" fx:controller="bisq.desktop.main.funds.locked.LockedView"
|
||||
|
@ -35,5 +39,9 @@
|
|||
<TableColumn fx:id="balanceColumn" minWidth="110"/>
|
||||
</columns>
|
||||
</TableView>
|
||||
|
||||
<HBox spacing="10">
|
||||
<Label fx:id="numItems"/>
|
||||
<Region fx:id="spacer"/>
|
||||
<AutoTooltipButton fx:id="exportButton"/>
|
||||
</HBox>
|
||||
</VBox>
|
||||
|
|
|
@ -19,12 +19,12 @@ package bisq.desktop.main.funds.locked;
|
|||
|
||||
import bisq.desktop.common.view.ActivatableView;
|
||||
import bisq.desktop.common.view.FxmlView;
|
||||
import bisq.desktop.components.AutoTooltipButton;
|
||||
import bisq.desktop.components.AutoTooltipLabel;
|
||||
import bisq.desktop.components.ExternalHyperlink;
|
||||
import bisq.desktop.components.HyperlinkWithIcon;
|
||||
import bisq.desktop.main.overlays.windows.OfferDetailsWindow;
|
||||
import bisq.desktop.main.overlays.windows.TradeDetailsWindow;
|
||||
import bisq.desktop.util.DisplayUtils;
|
||||
import bisq.desktop.util.GUIUtil;
|
||||
|
||||
import bisq.core.btc.listeners.BalanceListener;
|
||||
|
@ -43,6 +43,8 @@ import bisq.core.util.coin.CoinFormatter;
|
|||
import org.bitcoinj.core.Coin;
|
||||
import org.bitcoinj.core.Transaction;
|
||||
|
||||
import com.googlecode.jcsv.writer.CSVEntryConverter;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
|
||||
|
@ -50,12 +52,20 @@ import de.jensd.fx.fontawesome.AwesomeIcon;
|
|||
|
||||
import javafx.fxml.FXML;
|
||||
|
||||
import javafx.stage.Stage;
|
||||
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.TableCell;
|
||||
import javafx.scene.control.TableColumn;
|
||||
import javafx.scene.control.TableView;
|
||||
import javafx.scene.control.Tooltip;
|
||||
import javafx.scene.layout.HBox;
|
||||
import javafx.scene.layout.Priority;
|
||||
import javafx.scene.layout.Region;
|
||||
import javafx.scene.layout.VBox;
|
||||
|
||||
import javafx.geometry.Insets;
|
||||
|
||||
import javafx.beans.property.ReadOnlyObjectWrapper;
|
||||
|
||||
import javafx.collections.FXCollections;
|
||||
|
@ -77,6 +87,12 @@ public class LockedView extends ActivatableView<VBox, Void> {
|
|||
TableView<LockedListItem> tableView;
|
||||
@FXML
|
||||
TableColumn<LockedListItem, LockedListItem> dateColumn, detailsColumn, addressColumn, balanceColumn;
|
||||
@FXML
|
||||
Label numItems;
|
||||
@FXML
|
||||
Region spacer;
|
||||
@FXML
|
||||
AutoTooltipButton exportButton;
|
||||
|
||||
private final BtcWalletService btcWalletService;
|
||||
private final TradeManager tradeManager;
|
||||
|
@ -97,8 +113,13 @@ public class LockedView extends ActivatableView<VBox, Void> {
|
|||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@Inject
|
||||
private LockedView(BtcWalletService btcWalletService, TradeManager tradeManager, OpenOfferManager openOfferManager, Preferences preferences,
|
||||
@Named(FormattingUtils.BTC_FORMATTER_KEY) CoinFormatter formatter, OfferDetailsWindow offerDetailsWindow, TradeDetailsWindow tradeDetailsWindow) {
|
||||
private LockedView(BtcWalletService btcWalletService,
|
||||
TradeManager tradeManager,
|
||||
OpenOfferManager openOfferManager,
|
||||
Preferences preferences,
|
||||
@Named(FormattingUtils.BTC_FORMATTER_KEY) CoinFormatter formatter,
|
||||
OfferDetailsWindow offerDetailsWindow,
|
||||
TradeDetailsWindow tradeDetailsWindow) {
|
||||
this.btcWalletService = btcWalletService;
|
||||
this.tradeManager = tradeManager;
|
||||
this.openOfferManager = openOfferManager;
|
||||
|
@ -138,6 +159,10 @@ public class LockedView extends ActivatableView<VBox, Void> {
|
|||
};
|
||||
openOfferListChangeListener = c -> updateList();
|
||||
tradeListChangeListener = c -> updateList();
|
||||
|
||||
HBox.setHgrow(spacer, Priority.ALWAYS);
|
||||
numItems.setPadding(new Insets(-5, 0, 0, 10));
|
||||
exportButton.updateText(Res.get("shared.exportCSV"));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -149,6 +174,33 @@ public class LockedView extends ActivatableView<VBox, Void> {
|
|||
updateList();
|
||||
|
||||
btcWalletService.addBalanceListener(balanceListener);
|
||||
|
||||
numItems.setText(Res.get("shared.numItemsLabel", sortedList.size()));
|
||||
exportButton.setOnAction(event -> {
|
||||
ObservableList<TableColumn<LockedListItem, ?>> tableColumns = tableView.getColumns();
|
||||
int reportColumns = tableColumns.size();
|
||||
CSVEntryConverter<LockedListItem> headerConverter = transactionsListItem -> {
|
||||
String[] columns = new String[reportColumns];
|
||||
for (int i = 0; i < columns.length; i++)
|
||||
columns[i] = ((AutoTooltipLabel) tableColumns.get(i).getGraphic()).getText();
|
||||
return columns;
|
||||
};
|
||||
CSVEntryConverter<LockedListItem> contentConverter = item -> {
|
||||
String[] columns = new String[reportColumns];
|
||||
columns[0] = item.getDateString();
|
||||
columns[1] = item.getDetails();
|
||||
columns[2] = item.getAddressString();
|
||||
columns[3] = item.getBalanceString();
|
||||
return columns;
|
||||
};
|
||||
|
||||
GUIUtil.exportCSV("lockedInTradesFunds.csv",
|
||||
headerConverter,
|
||||
contentConverter,
|
||||
new LockedListItem(),
|
||||
sortedList,
|
||||
(Stage) root.getScene().getWindow());
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -158,6 +210,7 @@ public class LockedView extends ActivatableView<VBox, Void> {
|
|||
sortedList.comparatorProperty().unbind();
|
||||
observableList.forEach(LockedListItem::cleanup);
|
||||
btcWalletService.removeBalanceListener(balanceListener);
|
||||
exportButton.setOnAction(null);
|
||||
}
|
||||
|
||||
|
||||
|
@ -169,7 +222,8 @@ public class LockedView extends ActivatableView<VBox, Void> {
|
|||
observableList.forEach(LockedListItem::cleanup);
|
||||
observableList.setAll(tradeManager.getTradesStreamWithFundsLockedIn()
|
||||
.map(trade -> {
|
||||
final Optional<AddressEntry> addressEntryOptional = btcWalletService.getAddressEntry(trade.getId(), AddressEntry.Context.MULTI_SIG);
|
||||
Optional<AddressEntry> addressEntryOptional = btcWalletService.getAddressEntry(trade.getId(),
|
||||
AddressEntry.Context.MULTI_SIG);
|
||||
return addressEntryOptional.map(addressEntry -> new LockedListItem(trade,
|
||||
addressEntry,
|
||||
btcWalletService,
|
||||
|
@ -227,9 +281,9 @@ public class LockedView extends ActivatableView<VBox, Void> {
|
|||
super.updateItem(item, empty);
|
||||
if (item != null && !empty) {
|
||||
if (getTradable(item).isPresent())
|
||||
setGraphic(new AutoTooltipLabel(DisplayUtils.formatDateTime(getTradable(item).get().getDate())));
|
||||
setGraphic(new AutoTooltipLabel(item.getDateString()));
|
||||
else
|
||||
setGraphic(new AutoTooltipLabel(Res.get("shared.noDateAvailable")));
|
||||
setGraphic(new AutoTooltipLabel(item.getDateString()));
|
||||
} else {
|
||||
setGraphic(null);
|
||||
}
|
||||
|
@ -257,13 +311,13 @@ public class LockedView extends ActivatableView<VBox, Void> {
|
|||
if (item != null && !empty) {
|
||||
Optional<Tradable> tradableOptional = getTradable(item);
|
||||
if (tradableOptional.isPresent()) {
|
||||
field = new HyperlinkWithIcon(Res.get("funds.locked.locked", item.getTrade().getShortId()),
|
||||
field = new HyperlinkWithIcon(item.getDetails(),
|
||||
AwesomeIcon.INFO_SIGN);
|
||||
field.setOnAction(event -> openDetailPopup(item));
|
||||
field.setTooltip(new Tooltip(Res.get("tooltip.openPopupForDetails")));
|
||||
setGraphic(field);
|
||||
} else {
|
||||
setGraphic(new AutoTooltipLabel(Res.get("shared.noDetailsAvailable")));
|
||||
setGraphic(new AutoTooltipLabel(item.getDetails()));
|
||||
}
|
||||
|
||||
} else {
|
||||
|
|
|
@ -18,12 +18,13 @@
|
|||
package bisq.desktop.main.funds.reserved;
|
||||
|
||||
import bisq.desktop.components.AutoTooltipLabel;
|
||||
import bisq.desktop.util.DisplayUtils;
|
||||
|
||||
import bisq.core.btc.listeners.BalanceListener;
|
||||
import bisq.core.btc.model.AddressEntry;
|
||||
import bisq.core.btc.wallet.BtcWalletService;
|
||||
import bisq.core.locale.Res;
|
||||
import bisq.core.offer.OpenOffer;
|
||||
import bisq.core.trade.Tradable;
|
||||
import bisq.core.util.coin.CoinFormatter;
|
||||
|
||||
import org.bitcoinj.core.Address;
|
||||
|
@ -34,26 +35,40 @@ import javafx.scene.control.Label;
|
|||
|
||||
import java.util.Optional;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
class ReservedListItem {
|
||||
private final BalanceListener balanceListener;
|
||||
private final Label balanceLabel;
|
||||
private final OpenOffer openOffer;
|
||||
private final AddressEntry addressEntry;
|
||||
private final BtcWalletService btcWalletService;
|
||||
private final CoinFormatter formatter;
|
||||
private final String addressString;
|
||||
private Coin balance;
|
||||
|
||||
public ReservedListItem(OpenOffer openOffer, AddressEntry addressEntry, BtcWalletService btcWalletService, CoinFormatter formatter) {
|
||||
@Getter
|
||||
private final Label balanceLabel;
|
||||
@Getter
|
||||
private final OpenOffer openOffer;
|
||||
@Getter
|
||||
private final AddressEntry addressEntry;
|
||||
@Getter
|
||||
private final String addressString;
|
||||
@Getter
|
||||
private final Address address;
|
||||
@Getter
|
||||
private Coin balance;
|
||||
@Getter
|
||||
private String balanceString;
|
||||
|
||||
public ReservedListItem(OpenOffer openOffer,
|
||||
AddressEntry addressEntry,
|
||||
BtcWalletService btcWalletService,
|
||||
CoinFormatter formatter) {
|
||||
this.openOffer = openOffer;
|
||||
this.addressEntry = addressEntry;
|
||||
this.btcWalletService = btcWalletService;
|
||||
this.formatter = formatter;
|
||||
addressString = addressEntry.getAddressString();
|
||||
|
||||
// balance
|
||||
address = addressEntry.getAddress();
|
||||
balanceLabel = new AutoTooltipLabel();
|
||||
balanceListener = new BalanceListener(getAddress()) {
|
||||
balanceListener = new BalanceListener(address) {
|
||||
@Override
|
||||
public void onBalanceChanged(Coin balance, Transaction tx) {
|
||||
updateBalance();
|
||||
|
@ -63,41 +78,40 @@ class ReservedListItem {
|
|||
updateBalance();
|
||||
}
|
||||
|
||||
ReservedListItem() {
|
||||
this.openOffer = null;
|
||||
this.addressEntry = null;
|
||||
this.btcWalletService = null;
|
||||
this.formatter = null;
|
||||
addressString = null;
|
||||
address = null;
|
||||
balanceLabel = null;
|
||||
balanceListener = null;
|
||||
}
|
||||
|
||||
public void cleanup() {
|
||||
btcWalletService.removeBalanceListener(balanceListener);
|
||||
}
|
||||
|
||||
private void updateBalance() {
|
||||
final Optional<AddressEntry> addressEntryOptional = btcWalletService.getAddressEntry(openOffer.getId(), AddressEntry.Context.RESERVED_FOR_TRADE);
|
||||
Optional<AddressEntry> addressEntryOptional = btcWalletService.getAddressEntry(openOffer.getId(),
|
||||
AddressEntry.Context.RESERVED_FOR_TRADE);
|
||||
addressEntryOptional.ifPresent(addressEntry -> {
|
||||
balance = btcWalletService.getBalanceForAddress(addressEntry.getAddress());
|
||||
if (balance != null)
|
||||
balanceLabel.setText(formatter.formatCoin(balance));
|
||||
if (balance != null) {
|
||||
balanceString = formatter.formatCoin(balance);
|
||||
balanceLabel.setText(balanceString);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private Address getAddress() {
|
||||
return addressEntry.getAddress();
|
||||
public String getDateAsString() {
|
||||
return DisplayUtils.formatDateTime(openOffer.getDate());
|
||||
}
|
||||
|
||||
public AddressEntry getAddressEntry() {
|
||||
return addressEntry;
|
||||
public String getDetails() {
|
||||
return openOffer != null ?
|
||||
Res.get("funds.reserved.reserved", openOffer.getShortId()) :
|
||||
Res.get("shared.noDetailsAvailable");
|
||||
}
|
||||
|
||||
public Label getBalanceLabel() {
|
||||
return balanceLabel;
|
||||
}
|
||||
|
||||
public Coin getBalance() {
|
||||
return balance;
|
||||
}
|
||||
|
||||
public String getAddressString() {
|
||||
return addressString;
|
||||
}
|
||||
|
||||
public Tradable getOpenOffer() {
|
||||
return openOffer;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -17,8 +17,12 @@
|
|||
~ along with Bisq. If not, see <http://www.gnu.org/licenses/>.
|
||||
-->
|
||||
|
||||
<?import bisq.desktop.components.AutoTooltipButton?>
|
||||
<?import javafx.scene.control.Label?>
|
||||
<?import javafx.scene.control.TableColumn?>
|
||||
<?import javafx.scene.control.TableView?>
|
||||
<?import javafx.scene.layout.HBox?>
|
||||
<?import javafx.scene.layout.Region?>
|
||||
<?import javafx.scene.layout.VBox?>
|
||||
<?import javafx.geometry.Insets?>
|
||||
<VBox fx:id="root" fx:controller="bisq.desktop.main.funds.reserved.ReservedView"
|
||||
|
@ -35,5 +39,9 @@
|
|||
<TableColumn fx:id="balanceColumn" minWidth="110"/>
|
||||
</columns>
|
||||
</TableView>
|
||||
|
||||
<HBox spacing="10">
|
||||
<Label fx:id="numItems"/>
|
||||
<Region fx:id="spacer"/>
|
||||
<AutoTooltipButton fx:id="exportButton"/>
|
||||
</HBox>
|
||||
</VBox>
|
||||
|
|
|
@ -19,12 +19,12 @@ package bisq.desktop.main.funds.reserved;
|
|||
|
||||
import bisq.desktop.common.view.ActivatableView;
|
||||
import bisq.desktop.common.view.FxmlView;
|
||||
import bisq.desktop.components.AutoTooltipButton;
|
||||
import bisq.desktop.components.AutoTooltipLabel;
|
||||
import bisq.desktop.components.ExternalHyperlink;
|
||||
import bisq.desktop.components.HyperlinkWithIcon;
|
||||
import bisq.desktop.main.overlays.windows.OfferDetailsWindow;
|
||||
import bisq.desktop.main.overlays.windows.TradeDetailsWindow;
|
||||
import bisq.desktop.util.DisplayUtils;
|
||||
import bisq.desktop.util.GUIUtil;
|
||||
|
||||
import bisq.core.btc.listeners.BalanceListener;
|
||||
|
@ -43,6 +43,8 @@ import bisq.core.util.coin.CoinFormatter;
|
|||
import org.bitcoinj.core.Coin;
|
||||
import org.bitcoinj.core.Transaction;
|
||||
|
||||
import com.googlecode.jcsv.writer.CSVEntryConverter;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
|
||||
|
@ -50,12 +52,20 @@ import de.jensd.fx.fontawesome.AwesomeIcon;
|
|||
|
||||
import javafx.fxml.FXML;
|
||||
|
||||
import javafx.stage.Stage;
|
||||
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.TableCell;
|
||||
import javafx.scene.control.TableColumn;
|
||||
import javafx.scene.control.TableView;
|
||||
import javafx.scene.control.Tooltip;
|
||||
import javafx.scene.layout.HBox;
|
||||
import javafx.scene.layout.Priority;
|
||||
import javafx.scene.layout.Region;
|
||||
import javafx.scene.layout.VBox;
|
||||
|
||||
import javafx.geometry.Insets;
|
||||
|
||||
import javafx.beans.property.ReadOnlyObjectWrapper;
|
||||
|
||||
import javafx.collections.FXCollections;
|
||||
|
@ -77,6 +87,12 @@ public class ReservedView extends ActivatableView<VBox, Void> {
|
|||
TableView<ReservedListItem> tableView;
|
||||
@FXML
|
||||
TableColumn<ReservedListItem, ReservedListItem> dateColumn, detailsColumn, addressColumn, balanceColumn;
|
||||
@FXML
|
||||
Label numItems;
|
||||
@FXML
|
||||
Region spacer;
|
||||
@FXML
|
||||
AutoTooltipButton exportButton;
|
||||
|
||||
private final BtcWalletService btcWalletService;
|
||||
private final TradeManager tradeManager;
|
||||
|
@ -97,8 +113,13 @@ public class ReservedView extends ActivatableView<VBox, Void> {
|
|||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@Inject
|
||||
private ReservedView(BtcWalletService btcWalletService, TradeManager tradeManager, OpenOfferManager openOfferManager, Preferences preferences,
|
||||
@Named(FormattingUtils.BTC_FORMATTER_KEY) CoinFormatter formatter, OfferDetailsWindow offerDetailsWindow, TradeDetailsWindow tradeDetailsWindow) {
|
||||
private ReservedView(BtcWalletService btcWalletService,
|
||||
TradeManager tradeManager,
|
||||
OpenOfferManager openOfferManager,
|
||||
Preferences preferences,
|
||||
@Named(FormattingUtils.BTC_FORMATTER_KEY) CoinFormatter formatter,
|
||||
OfferDetailsWindow offerDetailsWindow,
|
||||
TradeDetailsWindow tradeDetailsWindow) {
|
||||
this.btcWalletService = btcWalletService;
|
||||
this.tradeManager = tradeManager;
|
||||
this.openOfferManager = openOfferManager;
|
||||
|
@ -138,6 +159,10 @@ public class ReservedView extends ActivatableView<VBox, Void> {
|
|||
};
|
||||
openOfferListChangeListener = c -> updateList();
|
||||
tradeListChangeListener = c -> updateList();
|
||||
|
||||
HBox.setHgrow(spacer, Priority.ALWAYS);
|
||||
numItems.setPadding(new Insets(-5, 0, 0, 10));
|
||||
exportButton.updateText(Res.get("shared.exportCSV"));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -149,6 +174,33 @@ public class ReservedView extends ActivatableView<VBox, Void> {
|
|||
updateList();
|
||||
|
||||
btcWalletService.addBalanceListener(balanceListener);
|
||||
|
||||
numItems.setText(Res.get("shared.numItemsLabel", sortedList.size()));
|
||||
exportButton.setOnAction(event -> {
|
||||
ObservableList<TableColumn<ReservedListItem, ?>> tableColumns = tableView.getColumns();
|
||||
int reportColumns = tableColumns.size();
|
||||
CSVEntryConverter<ReservedListItem> headerConverter = transactionsListItem -> {
|
||||
String[] columns = new String[reportColumns];
|
||||
for (int i = 0; i < columns.length; i++)
|
||||
columns[i] = ((AutoTooltipLabel) tableColumns.get(i).getGraphic()).getText();
|
||||
return columns;
|
||||
};
|
||||
CSVEntryConverter<ReservedListItem> contentConverter = item -> {
|
||||
String[] columns = new String[reportColumns];
|
||||
columns[0] = item.getDateAsString();
|
||||
columns[1] = item.getDetails();
|
||||
columns[2] = item.getAddressString();
|
||||
columns[3] = item.getBalanceString();
|
||||
return columns;
|
||||
};
|
||||
|
||||
GUIUtil.exportCSV("reservedInOffersFunds.csv",
|
||||
headerConverter,
|
||||
contentConverter,
|
||||
new ReservedListItem(),
|
||||
sortedList,
|
||||
(Stage) root.getScene().getWindow());
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -158,6 +210,7 @@ public class ReservedView extends ActivatableView<VBox, Void> {
|
|||
sortedList.comparatorProperty().unbind();
|
||||
observableList.forEach(ReservedListItem::cleanup);
|
||||
btcWalletService.removeBalanceListener(balanceListener);
|
||||
exportButton.setOnAction(null);
|
||||
}
|
||||
|
||||
|
||||
|
@ -226,9 +279,9 @@ public class ReservedView extends ActivatableView<VBox, Void> {
|
|||
public void updateItem(final ReservedListItem item, boolean empty) {
|
||||
super.updateItem(item, empty);
|
||||
if (item != null && !empty) {
|
||||
if (getTradable(item).isPresent())
|
||||
setGraphic(new AutoTooltipLabel(DisplayUtils.formatDateTime(getTradable(item).get().getDate())));
|
||||
else
|
||||
if (getTradable(item).isPresent()) {
|
||||
setGraphic(new AutoTooltipLabel(item.getDateAsString()));
|
||||
} else
|
||||
setGraphic(new AutoTooltipLabel(Res.get("shared.noDateAvailable")));
|
||||
} else {
|
||||
setGraphic(null);
|
||||
|
@ -257,13 +310,12 @@ public class ReservedView extends ActivatableView<VBox, Void> {
|
|||
if (item != null && !empty) {
|
||||
Optional<Tradable> tradableOptional = getTradable(item);
|
||||
if (tradableOptional.isPresent()) {
|
||||
field = new HyperlinkWithIcon(Res.get("funds.reserved.reserved", item.getOpenOffer().getShortId()),
|
||||
AwesomeIcon.INFO_SIGN);
|
||||
field = new HyperlinkWithIcon(item.getDetails(), AwesomeIcon.INFO_SIGN);
|
||||
field.setOnAction(event -> openDetailPopup(item));
|
||||
field.setTooltip(new Tooltip(Res.get("tooltip.openPopupForDetails")));
|
||||
setGraphic(field);
|
||||
} else {
|
||||
setGraphic(new AutoTooltipLabel(Res.get("shared.noDetailsAvailable")));
|
||||
setGraphic(new AutoTooltipLabel(item.getDetails()));
|
||||
}
|
||||
|
||||
} else {
|
||||
|
|
|
@ -18,8 +18,11 @@
|
|||
-->
|
||||
|
||||
<?import bisq.desktop.components.AutoTooltipButton?>
|
||||
<?import javafx.scene.control.Label?>
|
||||
<?import javafx.scene.control.TableColumn?>
|
||||
<?import javafx.scene.control.TableView?>
|
||||
<?import javafx.scene.layout.HBox?>
|
||||
<?import javafx.scene.layout.Region?>
|
||||
<?import javafx.scene.layout.VBox?>
|
||||
<?import javafx.geometry.Insets?>
|
||||
<VBox fx:id="root" fx:controller="bisq.desktop.main.funds.transactions.TransactionsView"
|
||||
|
@ -34,10 +37,14 @@
|
|||
<TableColumn fx:id="addressColumn" minWidth="260"/>
|
||||
<TableColumn fx:id="transactionColumn" minWidth="180"/>
|
||||
<TableColumn fx:id="amountColumn" minWidth="130" maxWidth="130"/>
|
||||
<TableColumn fx:id="memoColumn" minWidth="50" maxWidth="50"/>
|
||||
<TableColumn fx:id="confidenceColumn" minWidth="130" maxWidth="130"/>
|
||||
<TableColumn fx:id="memoColumn" minWidth="40"/>
|
||||
<TableColumn fx:id="confidenceColumn" minWidth="120" maxWidth="130"/>
|
||||
<TableColumn fx:id="revertTxColumn" sortable="false" minWidth="110" maxWidth="110" visible="false"/>
|
||||
</columns>
|
||||
</TableView>
|
||||
<AutoTooltipButton fx:id="exportButton"/>
|
||||
<HBox spacing="10">
|
||||
<Label fx:id="numItems"/>
|
||||
<Region fx:id="spacer"/>
|
||||
<AutoTooltipButton fx:id="exportButton"/>
|
||||
</HBox>
|
||||
</VBox>
|
||||
|
|
|
@ -56,14 +56,20 @@ import javafx.stage.Stage;
|
|||
|
||||
import javafx.scene.Scene;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.TableCell;
|
||||
import javafx.scene.control.TableColumn;
|
||||
import javafx.scene.control.TableView;
|
||||
import javafx.scene.control.Tooltip;
|
||||
import javafx.scene.input.KeyCode;
|
||||
import javafx.scene.input.KeyEvent;
|
||||
import javafx.scene.layout.HBox;
|
||||
import javafx.scene.layout.Priority;
|
||||
import javafx.scene.layout.Region;
|
||||
import javafx.scene.layout.VBox;
|
||||
|
||||
import javafx.geometry.Insets;
|
||||
|
||||
import javafx.beans.property.ReadOnlyObjectWrapper;
|
||||
|
||||
import javafx.event.EventHandler;
|
||||
|
@ -80,11 +86,16 @@ import javax.annotation.Nullable;
|
|||
@FxmlView
|
||||
public class TransactionsView extends ActivatableView<VBox, Void> {
|
||||
|
||||
|
||||
@FXML
|
||||
TableView<TransactionsListItem> tableView;
|
||||
@FXML
|
||||
TableColumn<TransactionsListItem, TransactionsListItem> dateColumn, detailsColumn, addressColumn, transactionColumn, amountColumn, memoColumn, confidenceColumn, revertTxColumn;
|
||||
@FXML
|
||||
Label numItems;
|
||||
@FXML
|
||||
Region spacer;
|
||||
@FXML
|
||||
AutoTooltipButton exportButton;
|
||||
|
||||
private final DisplayedTransactions displayedTransactions;
|
||||
|
@ -180,6 +191,8 @@ public class TransactionsView extends ActivatableView<VBox, Void> {
|
|||
}
|
||||
};
|
||||
|
||||
HBox.setHgrow(spacer, Priority.ALWAYS);
|
||||
numItems.setPadding(new Insets(-5, 0, 0, 10));
|
||||
exportButton.updateText(Res.get("shared.exportCSV"));
|
||||
}
|
||||
|
||||
|
@ -195,6 +208,7 @@ public class TransactionsView extends ActivatableView<VBox, Void> {
|
|||
if (scene != null)
|
||||
scene.addEventHandler(KeyEvent.KEY_RELEASED, keyEventEventHandler);
|
||||
|
||||
numItems.setText(Res.get("shared.numItemsLabel", sortedDisplayedTransactions.size()));
|
||||
exportButton.setOnAction(event -> {
|
||||
final ObservableList<TableColumn<TransactionsListItem, ?>> tableColumns = tableView.getColumns();
|
||||
final int reportColumns = tableColumns.size() - 1; // CSV report excludes the last column (an icon)
|
||||
|
|
|
@ -20,10 +20,12 @@
|
|||
<?import bisq.desktop.components.AutoTooltipButton?>
|
||||
<?import bisq.desktop.components.AutoTooltipLabel?>
|
||||
<?import bisq.desktop.components.InputTextField?>
|
||||
<?import javafx.scene.control.Label?>
|
||||
<?import javafx.scene.control.TableColumn?>
|
||||
<?import javafx.scene.control.TableView?>
|
||||
<?import javafx.scene.layout.HBox?>
|
||||
<?import javafx.scene.layout.Pane?>
|
||||
<?import javafx.scene.layout.Region?>
|
||||
<?import javafx.scene.layout.VBox?>
|
||||
<?import javafx.geometry.Insets?>
|
||||
<VBox fx:id="root" fx:controller="bisq.desktop.main.portfolio.closedtrades.ClosedTradesView"
|
||||
|
@ -32,6 +34,12 @@
|
|||
<Insets bottom="15.0" left="15.0" right="15.0" top="15.0"/>
|
||||
</padding>
|
||||
|
||||
<HBox fx:id="searchBox">
|
||||
<AutoTooltipLabel fx:id="filterLabel"/>
|
||||
<InputTextField fx:id="filterTextField" minWidth="300"/>
|
||||
<Pane fx:id="searchBoxSpacer"/>
|
||||
</HBox>
|
||||
|
||||
<TableView fx:id="tableView" VBox.vgrow="ALWAYS">
|
||||
<columns>
|
||||
<TableColumn fx:id="tradeIdColumn" minWidth="110" maxWidth="120"/>
|
||||
|
@ -50,10 +58,10 @@
|
|||
<TableColumn fx:id="avatarColumn" minWidth="40" maxWidth="40"/>
|
||||
</columns>
|
||||
</TableView>
|
||||
<HBox fx:id="footerBox">
|
||||
<AutoTooltipLabel fx:id="filterLabel"/>
|
||||
<InputTextField fx:id="filterTextField" minWidth="300"/>
|
||||
<Pane fx:id="spacer"/>
|
||||
|
||||
<HBox spacing="10">
|
||||
<Label fx:id="numItems"/>
|
||||
<Region fx:id="footerSpacer"/>
|
||||
<AutoTooltipButton fx:id="exportButton"/>
|
||||
</HBox>
|
||||
</VBox>
|
||||
|
|
|
@ -53,6 +53,7 @@ import javafx.fxml.FXML;
|
|||
import javafx.stage.Stage;
|
||||
|
||||
import javafx.scene.Node;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.TableCell;
|
||||
import javafx.scene.control.TableColumn;
|
||||
import javafx.scene.control.TableView;
|
||||
|
@ -60,6 +61,7 @@ import javafx.scene.control.Tooltip;
|
|||
import javafx.scene.layout.HBox;
|
||||
import javafx.scene.layout.Pane;
|
||||
import javafx.scene.layout.Priority;
|
||||
import javafx.scene.layout.Region;
|
||||
import javafx.scene.layout.VBox;
|
||||
|
||||
import javafx.geometry.Insets;
|
||||
|
@ -114,15 +116,19 @@ public class ClosedTradesView extends ActivatableViewAndModel<VBox, ClosedTrades
|
|||
txFeeColumn, tradeFeeColumn, buyerSecurityDepositColumn, sellerSecurityDepositColumn,
|
||||
marketColumn, directionColumn, dateColumn, tradeIdColumn, stateColumn, avatarColumn;
|
||||
@FXML
|
||||
HBox footerBox;
|
||||
HBox searchBox;
|
||||
@FXML
|
||||
AutoTooltipLabel filterLabel;
|
||||
@FXML
|
||||
InputTextField filterTextField;
|
||||
@FXML
|
||||
Pane spacer;
|
||||
Pane searchBoxSpacer;
|
||||
@FXML
|
||||
AutoTooltipButton exportButton;
|
||||
@FXML
|
||||
Label numItems;
|
||||
@FXML
|
||||
Region footerSpacer;
|
||||
|
||||
private final OfferDetailsWindow offerDetailsWindow;
|
||||
private final Preferences preferences;
|
||||
|
@ -225,14 +231,17 @@ public class ClosedTradesView extends ActivatableViewAndModel<VBox, ClosedTrades
|
|||
dateColumn.setSortType(TableColumn.SortType.DESCENDING);
|
||||
tableView.getSortOrder().add(dateColumn);
|
||||
|
||||
filterLabel.setText(Res.getWithCol("support.filter"));
|
||||
filterTextField.setPromptText(Res.get("support.filter.prompt"));
|
||||
filterLabel.setText(Res.get("shared.filter"));
|
||||
HBox.setMargin(filterLabel, new Insets(5, 0, 0, 10));
|
||||
filterTextFieldListener = (observable, oldValue, newValue) -> applyFilteredListPredicate(filterTextField.getText());
|
||||
footerBox.setSpacing(5);
|
||||
HBox.setHgrow(spacer, Priority.ALWAYS);
|
||||
searchBox.setSpacing(5);
|
||||
HBox.setHgrow(searchBoxSpacer, Priority.ALWAYS);
|
||||
exportButton.updateText(Res.get("shared.exportCSV"));
|
||||
HBox.setMargin(exportButton, new Insets(0, 10, 0, 0));
|
||||
|
||||
HBox.setHgrow(footerSpacer, Priority.ALWAYS);
|
||||
numItems.setPadding(new Insets(-5, 0, 0, 10));
|
||||
exportButton.updateText(Res.get("shared.exportCSV"));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -244,6 +253,7 @@ public class ClosedTradesView extends ActivatableViewAndModel<VBox, ClosedTrades
|
|||
|
||||
tableView.setItems(sortedList);
|
||||
|
||||
numItems.setText(Res.get("shared.numItemsLabel", sortedList.size()));
|
||||
exportButton.setOnAction(event -> {
|
||||
final ObservableList<TableColumn<ClosedTradableListItem, ?>> tableColumns = tableView.getColumns();
|
||||
CSVEntryConverter<ClosedTradableListItem> headerConverter = transactionsListItem -> {
|
||||
|
|
|
@ -19,18 +19,17 @@ package bisq.desktop.main.portfolio.failedtrades;
|
|||
|
||||
import bisq.core.trade.Trade;
|
||||
|
||||
/**
|
||||
* We could remove that wrapper if it is not needed for additional UI only fields.
|
||||
*/
|
||||
class FailedTradesListItem {
|
||||
import lombok.Getter;
|
||||
|
||||
class FailedTradesListItem {
|
||||
@Getter
|
||||
private final Trade trade;
|
||||
|
||||
FailedTradesListItem(Trade trade) {
|
||||
this.trade = trade;
|
||||
}
|
||||
|
||||
Trade getTrade() {
|
||||
return trade;
|
||||
FailedTradesListItem() {
|
||||
this.trade = null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,8 +17,12 @@
|
|||
~ along with Bisq. If not, see <http://www.gnu.org/licenses/>.
|
||||
-->
|
||||
|
||||
<?import bisq.desktop.components.AutoTooltipButton?>
|
||||
<?import javafx.scene.control.Label?>
|
||||
<?import javafx.scene.control.TableColumn?>
|
||||
<?import javafx.scene.control.TableView?>
|
||||
<?import javafx.scene.layout.HBox?>
|
||||
<?import javafx.scene.layout.Region?>
|
||||
<?import javafx.scene.layout.VBox?>
|
||||
<?import javafx.geometry.Insets?>
|
||||
<VBox fx:id="root" fx:controller="bisq.desktop.main.portfolio.failedtrades.FailedTradesView"
|
||||
|
@ -40,4 +44,9 @@
|
|||
<TableColumn fx:id="removeTradeColumn" minWidth="40" maxWidth="40"/>
|
||||
</columns>
|
||||
</TableView>
|
||||
<HBox spacing="10">
|
||||
<Label fx:id="numItems"/>
|
||||
<Region fx:id="spacer"/>
|
||||
<AutoTooltipButton fx:id="exportButton"/>
|
||||
</HBox>
|
||||
</VBox>
|
||||
|
|
|
@ -19,11 +19,13 @@ package bisq.desktop.main.portfolio.failedtrades;
|
|||
|
||||
import bisq.desktop.common.view.ActivatableViewAndModel;
|
||||
import bisq.desktop.common.view.FxmlView;
|
||||
import bisq.desktop.components.AutoTooltipButton;
|
||||
import bisq.desktop.components.AutoTooltipLabel;
|
||||
import bisq.desktop.components.HyperlinkWithIcon;
|
||||
import bisq.desktop.main.overlays.popups.Popup;
|
||||
import bisq.desktop.main.overlays.windows.TradeDetailsWindow;
|
||||
import bisq.desktop.util.FormBuilder;
|
||||
import bisq.desktop.util.GUIUtil;
|
||||
|
||||
import bisq.core.locale.Res;
|
||||
import bisq.core.trade.Trade;
|
||||
|
@ -31,6 +33,8 @@ import bisq.core.trade.Trade;
|
|||
import bisq.common.config.Config;
|
||||
import bisq.common.util.Utilities;
|
||||
|
||||
import com.googlecode.jcsv.writer.CSVEntryConverter;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
|
||||
|
@ -40,6 +44,8 @@ import com.jfoenix.controls.JFXButton;
|
|||
|
||||
import javafx.fxml.FXML;
|
||||
|
||||
import javafx.stage.Stage;
|
||||
|
||||
import javafx.scene.Scene;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.TableCell;
|
||||
|
@ -48,12 +54,18 @@ import javafx.scene.control.TableView;
|
|||
import javafx.scene.control.Tooltip;
|
||||
import javafx.scene.input.KeyCode;
|
||||
import javafx.scene.input.KeyEvent;
|
||||
import javafx.scene.layout.HBox;
|
||||
import javafx.scene.layout.Priority;
|
||||
import javafx.scene.layout.Region;
|
||||
import javafx.scene.layout.VBox;
|
||||
|
||||
import javafx.geometry.Insets;
|
||||
|
||||
import javafx.beans.property.ReadOnlyObjectWrapper;
|
||||
|
||||
import javafx.event.EventHandler;
|
||||
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.collections.transformation.SortedList;
|
||||
|
||||
import javafx.util.Callback;
|
||||
|
@ -68,6 +80,13 @@ public class FailedTradesView extends ActivatableViewAndModel<VBox, FailedTrades
|
|||
@FXML
|
||||
TableColumn<FailedTradesListItem, FailedTradesListItem> priceColumn, amountColumn, volumeColumn,
|
||||
marketColumn, directionColumn, dateColumn, tradeIdColumn, stateColumn, removeTradeColumn;
|
||||
@FXML
|
||||
Label numItems;
|
||||
@FXML
|
||||
Region spacer;
|
||||
@FXML
|
||||
AutoTooltipButton exportButton;
|
||||
|
||||
private final TradeDetailsWindow tradeDetailsWindow;
|
||||
private SortedList<FailedTradesListItem> sortedList;
|
||||
private EventHandler<KeyEvent> keyEventEventHandler;
|
||||
|
@ -137,6 +156,10 @@ public class FailedTradesView extends ActivatableViewAndModel<VBox, FailedTrades
|
|||
}
|
||||
}
|
||||
};
|
||||
|
||||
HBox.setHgrow(spacer, Priority.ALWAYS);
|
||||
numItems.setPadding(new Insets(-5, 0, 0, 10));
|
||||
exportButton.updateText(Res.get("shared.exportCSV"));
|
||||
}
|
||||
|
||||
private void onUnfail() {
|
||||
|
@ -174,6 +197,37 @@ public class FailedTradesView extends ActivatableViewAndModel<VBox, FailedTrades
|
|||
sortedList = new SortedList<>(model.getList());
|
||||
sortedList.comparatorProperty().bind(tableView.comparatorProperty());
|
||||
tableView.setItems(sortedList);
|
||||
|
||||
numItems.setText(Res.get("shared.numItemsLabel", sortedList.size()));
|
||||
exportButton.setOnAction(event -> {
|
||||
ObservableList<TableColumn<FailedTradesListItem, ?>> tableColumns = tableView.getColumns();
|
||||
int reportColumns = tableColumns.size() - 1; // CSV report excludes the last column (an icon)
|
||||
CSVEntryConverter<FailedTradesListItem> headerConverter = transactionsListItem -> {
|
||||
String[] columns = new String[reportColumns];
|
||||
for (int i = 0; i < columns.length; i++)
|
||||
columns[i] = ((AutoTooltipLabel) tableColumns.get(i).getGraphic()).getText();
|
||||
return columns;
|
||||
};
|
||||
CSVEntryConverter<FailedTradesListItem> contentConverter = item -> {
|
||||
String[] columns = new String[reportColumns];
|
||||
columns[0] = model.getTradeId(item);
|
||||
columns[1] = model.getDate(item);
|
||||
columns[2] = model.getMarketLabel(item);
|
||||
columns[3] = model.getPrice(item);
|
||||
columns[4] = model.getAmount(item);
|
||||
columns[5] = model.getVolume(item);
|
||||
columns[6] = model.getDirectionLabel(item);
|
||||
columns[7] = model.getState(item);
|
||||
return columns;
|
||||
};
|
||||
|
||||
GUIUtil.exportCSV("failedTrades.csv",
|
||||
headerConverter,
|
||||
contentConverter,
|
||||
new FailedTradesListItem(),
|
||||
sortedList,
|
||||
(Stage) root.getScene().getWindow());
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -20,19 +20,21 @@ package bisq.desktop.main.portfolio.openoffer;
|
|||
import bisq.core.offer.Offer;
|
||||
import bisq.core.offer.OpenOffer;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* We could remove that wrapper if it is not needed for additional UI only fields.
|
||||
*/
|
||||
class OpenOfferListItem {
|
||||
|
||||
@Getter
|
||||
private final OpenOffer openOffer;
|
||||
|
||||
public OpenOfferListItem(OpenOffer openOffer) {
|
||||
OpenOfferListItem(OpenOffer openOffer) {
|
||||
this.openOffer = openOffer;
|
||||
}
|
||||
|
||||
public OpenOffer getOpenOffer() {
|
||||
return openOffer;
|
||||
OpenOfferListItem() {
|
||||
openOffer = null;
|
||||
}
|
||||
|
||||
public Offer getOffer() {
|
||||
|
|
|
@ -17,8 +17,12 @@
|
|||
~ along with Bisq. If not, see <http://www.gnu.org/licenses/>.
|
||||
-->
|
||||
|
||||
<?import bisq.desktop.components.AutoTooltipButton?>
|
||||
<?import javafx.scene.control.Label?>
|
||||
<?import javafx.scene.control.TableColumn?>
|
||||
<?import javafx.scene.control.TableView?>
|
||||
<?import javafx.scene.layout.HBox?>
|
||||
<?import javafx.scene.layout.Region?>
|
||||
<?import javafx.scene.layout.VBox?>
|
||||
<?import javafx.geometry.Insets?>
|
||||
<VBox fx:id="root" fx:controller="bisq.desktop.main.portfolio.openoffer.OpenOffersView"
|
||||
|
@ -43,5 +47,9 @@
|
|||
<TableColumn fx:id="removeItemColumn" minWidth="50" maxWidth="60" sortable="false"/>
|
||||
</columns>
|
||||
</TableView>
|
||||
|
||||
<HBox spacing="10">
|
||||
<Label fx:id="numItems"/>
|
||||
<Region fx:id="spacer"/>
|
||||
<AutoTooltipButton fx:id="exportButton"/>
|
||||
</HBox>
|
||||
</VBox>
|
||||
|
|
|
@ -20,6 +20,7 @@ package bisq.desktop.main.portfolio.openoffer;
|
|||
import bisq.desktop.Navigation;
|
||||
import bisq.desktop.common.view.ActivatableViewAndModel;
|
||||
import bisq.desktop.common.view.FxmlView;
|
||||
import bisq.desktop.components.AutoTooltipButton;
|
||||
import bisq.desktop.components.AutoTooltipCheckBox;
|
||||
import bisq.desktop.components.AutoTooltipLabel;
|
||||
import bisq.desktop.components.AutoTooltipTableColumn;
|
||||
|
@ -30,28 +31,42 @@ import bisq.desktop.main.funds.withdrawal.WithdrawalView;
|
|||
import bisq.desktop.main.overlays.popups.Popup;
|
||||
import bisq.desktop.main.overlays.windows.OfferDetailsWindow;
|
||||
import bisq.desktop.main.portfolio.PortfolioView;
|
||||
import bisq.desktop.util.GUIUtil;
|
||||
|
||||
import bisq.core.locale.Res;
|
||||
import bisq.core.offer.OpenOffer;
|
||||
import bisq.core.user.DontShowAgainLookup;
|
||||
|
||||
import com.googlecode.jcsv.writer.CSVEntryConverter;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import de.jensd.fx.glyphs.materialdesignicons.MaterialDesignIcon;
|
||||
|
||||
import javafx.fxml.FXML;
|
||||
|
||||
import javafx.stage.Stage;
|
||||
|
||||
import javafx.scene.Node;
|
||||
import javafx.scene.Parent;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.CheckBox;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.TableCell;
|
||||
import javafx.scene.control.TableColumn;
|
||||
import javafx.scene.control.TableView;
|
||||
import javafx.scene.control.Tooltip;
|
||||
import javafx.scene.image.ImageView;
|
||||
import javafx.scene.layout.HBox;
|
||||
import javafx.scene.layout.Priority;
|
||||
import javafx.scene.layout.Region;
|
||||
import javafx.scene.layout.VBox;
|
||||
|
||||
import javafx.geometry.Insets;
|
||||
|
||||
import javafx.beans.property.ReadOnlyObjectWrapper;
|
||||
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.collections.transformation.SortedList;
|
||||
|
||||
import javafx.util.Callback;
|
||||
|
@ -71,6 +86,13 @@ public class OpenOffersView extends ActivatableViewAndModel<VBox, OpenOffersView
|
|||
TableColumn<OpenOfferListItem, OpenOfferListItem> priceColumn, deviationColumn, amountColumn, volumeColumn,
|
||||
marketColumn, directionColumn, dateColumn, offerIdColumn, deactivateItemColumn,
|
||||
removeItemColumn, editItemColumn, paymentMethodColumn;
|
||||
@FXML
|
||||
Label numItems;
|
||||
@FXML
|
||||
Region spacer;
|
||||
@FXML
|
||||
AutoTooltipButton exportButton;
|
||||
|
||||
private final Navigation navigation;
|
||||
private final OfferDetailsWindow offerDetailsWindow;
|
||||
private SortedList<OpenOfferListItem> sortedList;
|
||||
|
@ -121,7 +143,7 @@ public class OpenOffersView extends ActivatableViewAndModel<VBox, OpenOffersView
|
|||
amountColumn.setComparator(Comparator.comparing(o -> o.getOffer().getAmount()));
|
||||
priceColumn.setComparator(Comparator.comparing(o -> o.getOffer().getPrice(), Comparator.nullsFirst(Comparator.naturalOrder())));
|
||||
deviationColumn.setComparator(Comparator.comparing(o ->
|
||||
o.getOffer().isUseMarketBasedPrice() ? o.getOffer().getMarketPriceMargin() : 1,
|
||||
o.getOffer().isUseMarketBasedPrice() ? o.getOffer().getMarketPriceMargin() : 1,
|
||||
Comparator.nullsFirst(Comparator.naturalOrder())));
|
||||
volumeColumn.setComparator(Comparator.comparing(o -> o.getOffer().getVolume(), Comparator.nullsFirst(Comparator.naturalOrder())));
|
||||
dateColumn.setComparator(Comparator.comparing(o -> o.getOffer().getDate()));
|
||||
|
@ -129,6 +151,10 @@ public class OpenOffersView extends ActivatableViewAndModel<VBox, OpenOffersView
|
|||
|
||||
dateColumn.setSortType(TableColumn.SortType.DESCENDING);
|
||||
tableView.getSortOrder().add(dateColumn);
|
||||
|
||||
HBox.setHgrow(spacer, Priority.ALWAYS);
|
||||
numItems.setPadding(new Insets(-5, 0, 0, 10));
|
||||
exportButton.updateText(Res.get("shared.exportCSV"));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -136,6 +162,49 @@ public class OpenOffersView extends ActivatableViewAndModel<VBox, OpenOffersView
|
|||
sortedList = new SortedList<>(model.getList());
|
||||
sortedList.comparatorProperty().bind(tableView.comparatorProperty());
|
||||
tableView.setItems(sortedList);
|
||||
|
||||
numItems.setText(Res.get("shared.numItemsLabel", sortedList.size()));
|
||||
exportButton.setOnAction(event -> {
|
||||
ObservableList<TableColumn<OpenOfferListItem, ?>> tableColumns = tableView.getColumns();
|
||||
int reportColumns = tableColumns.size() - 2; // CSV report excludes the last columns (icons)
|
||||
CSVEntryConverter<OpenOfferListItem> headerConverter = transactionsListItem -> {
|
||||
String[] columns = new String[reportColumns];
|
||||
for (int i = 0; i < columns.length; i++) {
|
||||
Node graphic = tableColumns.get(i).getGraphic();
|
||||
if (graphic instanceof AutoTooltipLabel) {
|
||||
columns[i] = ((AutoTooltipLabel) graphic).getText();
|
||||
} else if (graphic instanceof HBox) {
|
||||
// Deviation has a Hbox with AutoTooltipLabel as first child in header
|
||||
columns[i] = ((AutoTooltipLabel) ((Parent) graphic).getChildrenUnmodifiable().get(0)).getText();
|
||||
} else {
|
||||
// Not expected
|
||||
columns[i] = "N/A";
|
||||
}
|
||||
}
|
||||
return columns;
|
||||
};
|
||||
CSVEntryConverter<OpenOfferListItem> contentConverter = item -> {
|
||||
String[] columns = new String[reportColumns];
|
||||
columns[0] = model.getOfferId(item);
|
||||
columns[1] = model.getDate(item);
|
||||
columns[2] = model.getMarketLabel(item);
|
||||
columns[3] = model.getPrice(item);
|
||||
columns[4] = model.getPriceDeviation(item);
|
||||
columns[5] = model.getAmount(item);
|
||||
columns[6] = model.getVolume(item);
|
||||
columns[7] = model.getPaymentMethod(item);
|
||||
columns[8] = model.getDirectionLabel(item);
|
||||
columns[9] = String.valueOf(!item.getOpenOffer().isDeactivated());
|
||||
return columns;
|
||||
};
|
||||
|
||||
GUIUtil.exportCSV("openOffers.csv",
|
||||
headerConverter,
|
||||
contentConverter,
|
||||
new OpenOfferListItem(),
|
||||
sortedList,
|
||||
(Stage) root.getScene().getWindow());
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -226,7 +295,7 @@ public class OpenOffersView extends ActivatableViewAndModel<VBox, OpenOffersView
|
|||
super.updateItem(item, empty);
|
||||
|
||||
if (item != null && !empty) {
|
||||
field = new HyperlinkWithIcon(model.getTradeId(item));
|
||||
field = new HyperlinkWithIcon(model.getOfferId(item));
|
||||
field.setOnAction(event -> offerDetailsWindow.show(item.getOffer()));
|
||||
field.setTooltip(new Tooltip(Res.get("tooltip.openPopupForDetails")));
|
||||
setGraphic(field);
|
||||
|
|
|
@ -27,8 +27,8 @@ import bisq.core.locale.Res;
|
|||
import bisq.core.monetary.Price;
|
||||
import bisq.core.offer.Offer;
|
||||
import bisq.core.offer.OpenOffer;
|
||||
import bisq.core.util.coin.BsqFormatter;
|
||||
import bisq.core.util.FormattingUtils;
|
||||
import bisq.core.util.coin.BsqFormatter;
|
||||
import bisq.core.util.coin.CoinFormatter;
|
||||
|
||||
import bisq.network.p2p.P2PService;
|
||||
|
@ -78,7 +78,7 @@ class OpenOffersViewModel extends ActivatableWithDataModel<OpenOffersDataModel>
|
|||
return dataModel.getList();
|
||||
}
|
||||
|
||||
String getTradeId(OpenOfferListItem item) {
|
||||
String getOfferId(OpenOfferListItem item) {
|
||||
return item.getOffer().getShortId();
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue