diff --git a/core/src/main/java/io/bitsquare/user/Preferences.java b/core/src/main/java/io/bitsquare/user/Preferences.java index 4a60f03bf9..141704b031 100644 --- a/core/src/main/java/io/bitsquare/user/Preferences.java +++ b/core/src/main/java/io/bitsquare/user/Preferences.java @@ -23,6 +23,7 @@ import io.bitsquare.app.Version; import io.bitsquare.btc.BitcoinNetwork; import io.bitsquare.btc.FeePolicy; import io.bitsquare.common.persistance.Persistable; +import io.bitsquare.common.util.Utilities; import io.bitsquare.locale.*; import io.bitsquare.storage.Storage; import io.nucleo.net.bridge.BridgeProvider; @@ -127,6 +128,7 @@ public final class Preferences implements Persistable { @Nullable private List bridgeAddresses; private List ignoreTradersList = new ArrayList<>(); + private String defaultPath; // Observable wrappers transient private final StringProperty btcDenominationProperty = new SimpleStringProperty(btcDenomination); @@ -148,6 +150,12 @@ public final class Preferences implements Persistable { this.storage = storage; this.bitsquareEnvironment = bitsquareEnvironment; + if (Utilities.isWindows()) + defaultPath = System.getenv("USERPROFILE"); + else + defaultPath = System.getProperty("user.home"); + + Preferences persisted = storage.initAndGetPersisted(this); if (persisted != null) { setBtcDenomination(persisted.btcDenomination); @@ -199,9 +207,12 @@ public final class Preferences implements Persistable { marketScreenCurrencyCode = persisted.getMarketScreenCurrencyCode(); buyScreenCurrencyCode = persisted.getBuyScreenCurrencyCode(); sellScreenCurrencyCode = persisted.getSellScreenCurrencyCode(); - ignoreTradersList = persisted.getIgnoreTradersList(); - if (ignoreTradersList == null) - ignoreTradersList = new ArrayList<>(); + + if (persisted.getIgnoreTradersList() != null) + ignoreTradersList = persisted.getIgnoreTradersList(); + + if (persisted.getDefaultPath() != null) + defaultPath = persisted.getDefaultPath(); } else { setFiatCurrencies(CurrencyUtil.getAllMainFiatCurrencies()); fiatCurrencies = new ArrayList<>(fiatCurrenciesAsObservable); @@ -441,6 +452,12 @@ public final class Preferences implements Persistable { storage.queueUpForSave(); } + public void setDefaultPath(String defaultPath) { + this.defaultPath = defaultPath; + storage.queueUpForSave(); + } + + /////////////////////////////////////////////////////////////////////////////////////////// // Getter /////////////////////////////////////////////////////////////////////////////////////////// @@ -589,6 +606,9 @@ public final class Preferences implements Persistable { return ignoreTradersList; } + public String getDefaultPath() { + return defaultPath; + } /////////////////////////////////////////////////////////////////////////////////////////// // Private /////////////////////////////////////////////////////////////////////////////////////////// diff --git a/gui/src/main/java/io/bitsquare/gui/main/account/content/altcoinaccounts/AltCoinAccountsDataModel.java b/gui/src/main/java/io/bitsquare/gui/main/account/content/altcoinaccounts/AltCoinAccountsDataModel.java index c1169d893b..39246bf9bd 100644 --- a/gui/src/main/java/io/bitsquare/gui/main/account/content/altcoinaccounts/AltCoinAccountsDataModel.java +++ b/gui/src/main/java/io/bitsquare/gui/main/account/content/altcoinaccounts/AltCoinAccountsDataModel.java @@ -19,14 +19,13 @@ package io.bitsquare.gui.main.account.content.altcoinaccounts; import com.google.inject.Inject; import io.bitsquare.gui.common.model.ActivatableDataModel; -import io.bitsquare.gui.main.overlays.popups.Popup; +import io.bitsquare.gui.util.GUIUtil; import io.bitsquare.locale.CryptoCurrency; import io.bitsquare.locale.FiatCurrency; import io.bitsquare.locale.TradeCurrency; import io.bitsquare.payment.CryptoCurrencyAccount; import io.bitsquare.payment.PaymentAccount; import io.bitsquare.payment.PaymentMethod; -import io.bitsquare.storage.Storage; import io.bitsquare.trade.TradeManager; import io.bitsquare.trade.offer.OpenOfferManager; import io.bitsquare.user.Preferences; @@ -34,9 +33,8 @@ import io.bitsquare.user.User; import javafx.collections.FXCollections; import javafx.collections.ObservableList; import javafx.collections.SetChangeListener; +import javafx.stage.Stage; -import javax.inject.Named; -import java.io.File; import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; @@ -47,18 +45,19 @@ class AltCoinAccountsDataModel extends ActivatableDataModel { private Preferences preferences; private final OpenOfferManager openOfferManager; private final TradeManager tradeManager; - private File storageDir; + private Stage stage; final ObservableList paymentAccounts = FXCollections.observableArrayList(); private final SetChangeListener setChangeListener; + private final String accountsFileName = "AltcoinPaymentAccounts"; @Inject public AltCoinAccountsDataModel(User user, Preferences preferences, OpenOfferManager openOfferManager, - TradeManager tradeManager, @Named("storage.dir") File storageDir) { + TradeManager tradeManager, Stage stage) { this.user = user; this.preferences = preferences; this.openOfferManager = openOfferManager; this.tradeManager = tradeManager; - this.storageDir = storageDir; + this.stage = stage; setChangeListener = change -> fillAndSortPaymentAccounts(); } @@ -104,7 +103,6 @@ class AltCoinAccountsDataModel extends ActivatableDataModel { } } - public boolean onDeleteAccount(PaymentAccount paymentAccount) { boolean isPaymentAccountUsed = openOfferManager.getOpenOffers().stream() .filter(o -> o.getOffer().getOffererPaymentAccountId().equals(paymentAccount.getId())) @@ -126,38 +124,12 @@ class AltCoinAccountsDataModel extends ActivatableDataModel { public void exportAccounts() { ArrayList accounts = new ArrayList<>(user.getPaymentAccounts().stream() - .filter(paymentAccount -> (paymentAccount instanceof CryptoCurrencyAccount)) + .filter(paymentAccount -> paymentAccount instanceof CryptoCurrencyAccount) .collect(Collectors.toList())); - if (!accounts.isEmpty()) { - Storage> paymentAccountsStorage = new Storage<>(storageDir); - paymentAccountsStorage.initAndGetPersisted(accounts, "AltcoinPaymentAccounts"); - paymentAccountsStorage.queueUpForSave(20); - new Popup<>().feedback("Payment accounts saved to data directory at:\n" + storageDir.getAbsolutePath()).show(); - } else { - new Popup<>().warning("You have no payment accounts set up for export.").show(); - } + GUIUtil.exportAccounts(accounts, accountsFileName, preferences, stage); } public void importAccounts() { - Storage> paymentAccountsStorage = new Storage<>(storageDir); - ArrayList persisted = paymentAccountsStorage.initAndGetPersisted("AltcoinPaymentAccounts"); - if (persisted != null) { - final StringBuilder msg = new StringBuilder(); - persisted.stream().forEach(paymentAccount -> { - final String id = paymentAccount.getId(); - - if (user.getPaymentAccount(id) == null) { - user.addPaymentAccount(paymentAccount); - msg.append("Payment account with id ").append(id).append("\n"); - } else { - msg.append("Payment account with id ").append(id).append(" exists already. We did not import that.").append("\n"); - } - }); - new Popup<>().feedback("Payment account imported from data directory at:\n" + storageDir.getAbsolutePath() + "\n\nImported accounts:\n" + msg).show(); - - } else { - new Popup<>().warning("No exported payment account has been found at data directory at: " + storageDir.getAbsolutePath()).show(); - } + GUIUtil.importAccounts(user, accountsFileName, preferences, stage); } - } diff --git a/gui/src/main/java/io/bitsquare/gui/main/account/content/backup/BackupView.java b/gui/src/main/java/io/bitsquare/gui/main/account/content/backup/BackupView.java index 7492796a71..5ef2c05621 100644 --- a/gui/src/main/java/io/bitsquare/gui/main/account/content/backup/BackupView.java +++ b/gui/src/main/java/io/bitsquare/gui/main/account/content/backup/BackupView.java @@ -80,7 +80,6 @@ public class BackupView extends ActivatableView { backupNow.setDisable(preferences.getBackupDirectory() == null || preferences.getBackupDirectory().length() == 0); backupNow.setDefaultButton(preferences.getBackupDirectory() != null); - addTitledGroupBg(root, ++gridRow, 2, "Backup wallet and data directory", Layout.GROUP_DISTANCE); } @@ -88,11 +87,12 @@ public class BackupView extends ActivatableView { protected void activate() { selectBackupDir.setOnAction(e -> { DirectoryChooser directoryChooser = new DirectoryChooser(); - directoryChooser.setInitialDirectory(new File(System.getProperty("user.home"))); + directoryChooser.setInitialDirectory(new File(preferences.getDefaultPath())); directoryChooser.setTitle("Select backup location"); File dir = directoryChooser.showDialog(stage); if (dir != null) { String backupDirectory = dir.getAbsolutePath(); + preferences.setDefaultPath(backupDirectory); backUpLocationTextField.setText(backupDirectory); preferences.setBackupDirectory(backupDirectory); backupNow.setDisable(false); @@ -130,6 +130,7 @@ public class BackupView extends ActivatableView { protected void deactivate() { selectBackupDir.setOnAction(null); openDataDir.setOnAction(null); + backupNow.setOnAction(null); } } diff --git a/gui/src/main/java/io/bitsquare/gui/main/account/content/fiataccounts/FiatAccountsDataModel.java b/gui/src/main/java/io/bitsquare/gui/main/account/content/fiataccounts/FiatAccountsDataModel.java index 704bdfd7b0..885be50200 100644 --- a/gui/src/main/java/io/bitsquare/gui/main/account/content/fiataccounts/FiatAccountsDataModel.java +++ b/gui/src/main/java/io/bitsquare/gui/main/account/content/fiataccounts/FiatAccountsDataModel.java @@ -19,14 +19,13 @@ package io.bitsquare.gui.main.account.content.fiataccounts; import com.google.inject.Inject; import io.bitsquare.gui.common.model.ActivatableDataModel; -import io.bitsquare.gui.main.overlays.popups.Popup; +import io.bitsquare.gui.util.GUIUtil; import io.bitsquare.locale.CryptoCurrency; import io.bitsquare.locale.FiatCurrency; import io.bitsquare.locale.TradeCurrency; import io.bitsquare.payment.CryptoCurrencyAccount; import io.bitsquare.payment.PaymentAccount; import io.bitsquare.payment.PaymentMethod; -import io.bitsquare.storage.Storage; import io.bitsquare.trade.TradeManager; import io.bitsquare.trade.offer.OpenOfferManager; import io.bitsquare.user.Preferences; @@ -34,9 +33,8 @@ import io.bitsquare.user.User; import javafx.collections.FXCollections; import javafx.collections.ObservableList; import javafx.collections.SetChangeListener; +import javafx.stage.Stage; -import javax.inject.Named; -import java.io.File; import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; @@ -47,18 +45,19 @@ class FiatAccountsDataModel extends ActivatableDataModel { private Preferences preferences; private final OpenOfferManager openOfferManager; private final TradeManager tradeManager; - private File storageDir; + private Stage stage; final ObservableList paymentAccounts = FXCollections.observableArrayList(); private final SetChangeListener setChangeListener; + private final String accountsFileName = "FiatPaymentAccounts"; @Inject public FiatAccountsDataModel(User user, Preferences preferences, OpenOfferManager openOfferManager, - TradeManager tradeManager, @Named("storage.dir") File storageDir) { + TradeManager tradeManager, Stage stage) { this.user = user; this.preferences = preferences; this.openOfferManager = openOfferManager; this.tradeManager = tradeManager; - this.storageDir = storageDir; + this.stage = stage; setChangeListener = change -> fillAndSortPaymentAccounts(); } @@ -128,35 +127,10 @@ class FiatAccountsDataModel extends ActivatableDataModel { ArrayList accounts = new ArrayList<>(user.getPaymentAccounts().stream() .filter(paymentAccount -> !(paymentAccount instanceof CryptoCurrencyAccount)) .collect(Collectors.toList())); - if (!accounts.isEmpty()) { - Storage> paymentAccountsStorage = new Storage<>(storageDir); - paymentAccountsStorage.initAndGetPersisted(accounts, "FiatPaymentAccounts"); - paymentAccountsStorage.queueUpForSave(20); - new Popup<>().feedback("Payment accounts saved to data directory at:\n" + storageDir.getAbsolutePath()).show(); - } else { - new Popup<>().warning("You have no payment accounts set up for export.").show(); - } + GUIUtil.exportAccounts(accounts, accountsFileName, preferences, stage); } public void importAccounts() { - Storage> paymentAccountsStorage = new Storage<>(storageDir); - ArrayList persisted = paymentAccountsStorage.initAndGetPersisted("FiatPaymentAccounts"); - if (persisted != null) { - final StringBuilder msg = new StringBuilder(); - persisted.stream().forEach(paymentAccount -> { - final String id = paymentAccount.getId(); - - if (user.getPaymentAccount(id) == null) { - user.addPaymentAccount(paymentAccount); - msg.append("Payment account with id ").append(id).append("\n"); - } else { - msg.append("Payment account with id ").append(id).append(" exists already. We did not import that.").append("\n"); - } - }); - new Popup<>().feedback("Payment account imported from data directory at:\n" + storageDir.getAbsolutePath() + "\n\nImported accounts:\n" + msg).show(); - - } else { - new Popup<>().warning("No exported payment account has been found at data directory at: " + storageDir.getAbsolutePath()).show(); - } + GUIUtil.importAccounts(user, accountsFileName, preferences, stage); } } diff --git a/gui/src/main/java/io/bitsquare/gui/util/GUIUtil.java b/gui/src/main/java/io/bitsquare/gui/util/GUIUtil.java index b5e3fba260..d05b40e091 100644 --- a/gui/src/main/java/io/bitsquare/gui/util/GUIUtil.java +++ b/gui/src/main/java/io/bitsquare/gui/util/GUIUtil.java @@ -19,13 +19,23 @@ package io.bitsquare.gui.util; import io.bitsquare.app.DevFlags; import io.bitsquare.gui.main.overlays.popups.Popup; +import io.bitsquare.payment.PaymentAccount; +import io.bitsquare.storage.Storage; import io.bitsquare.user.Preferences; +import io.bitsquare.user.User; import javafx.geometry.Orientation; import javafx.scene.Node; import javafx.scene.control.ScrollBar; +import javafx.stage.DirectoryChooser; +import javafx.stage.FileChooser; +import javafx.stage.Stage; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.io.File; +import java.nio.file.Paths; +import java.util.ArrayList; + public class GUIUtil { private static final Logger log = LoggerFactory.getLogger(GUIUtil.class); @@ -55,4 +65,58 @@ public class GUIUtil { runnable.run(); } } + + + public static void exportAccounts(ArrayList accounts, String fileName, Preferences preferences, Stage stage) { + if (!accounts.isEmpty()) { + DirectoryChooser directoryChooser = new DirectoryChooser(); + directoryChooser.setInitialDirectory(new File(preferences.getDefaultPath())); + directoryChooser.setTitle("Select export path"); + File dir = directoryChooser.showDialog(stage); + if (dir != null) { + String directory = dir.getAbsolutePath(); + preferences.setDefaultPath(directory); + Storage> paymentAccountsStorage = new Storage<>(new File(directory)); + paymentAccountsStorage.initAndGetPersisted(accounts, fileName); + paymentAccountsStorage.queueUpForSave(20); + new Popup<>().feedback("Payment accounts saved to path:\n" + Paths.get(directory, fileName).toAbsolutePath()).show(); + } + } else { + new Popup<>().warning("You don't have payment accounts set up for exporting.").show(); + } + } + + public static void importAccounts(User user, String fileName, Preferences preferences, Stage stage) { + FileChooser fileChooser = new FileChooser(); + fileChooser.setInitialDirectory(new File(preferences.getDefaultPath())); + fileChooser.setTitle("Select path to " + fileName); + File file = fileChooser.showOpenDialog(stage.getOwner()); + if (file != null) { + String path = file.getAbsolutePath(); + if (Paths.get(path).getFileName().toString().equals(fileName)) { + String directory = Paths.get(path).getParent().toString(); + preferences.setDefaultPath(directory); + Storage> paymentAccountsStorage = new Storage<>(new File(directory)); + ArrayList persisted = paymentAccountsStorage.initAndGetPersisted(fileName); + if (persisted != null) { + final StringBuilder msg = new StringBuilder(); + persisted.stream().forEach(paymentAccount -> { + final String id = paymentAccount.getId(); + if (user.getPaymentAccount(id) == null) { + user.addPaymentAccount(paymentAccount); + msg.append("Payment account with id ").append(id).append("\n"); + } else { + msg.append("We did not import payment account with id ").append(id).append(" because it exists already.\n"); + } + }); + new Popup<>().feedback("Payment account imported from path:\n" + path + "\n\nImported accounts:\n" + msg).show(); + + } else { + new Popup<>().warning("No exported payment accounts has been found at path: " + path + ".\n" + "File name is " + fileName + ".").show(); + } + } else { + new Popup<>().warning("The selected file is not the expected file for import. The expected file name is: " + fileName + ".").show(); + } + } + } }