Refactor everything

This commit is contained in:
Chris Beams 2014-11-22 13:44:24 +01:00
parent de82cfb1d6
commit cc2de07901
No known key found for this signature in database
GPG Key ID: 3D214F8F5BC5ED73
41 changed files with 442 additions and 588 deletions

View File

@ -15,22 +15,10 @@
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
*/
package io.bitsquare.gui.main.account.content.changepassword;
package io.bitsquare.gui;
import io.bitsquare.gui.UIModel;
import com.google.inject.Inject;
class ChangePasswordModel extends UIModel {
@Inject
public ChangePasswordModel() {
}
@SuppressWarnings("EmptyMethod")
void savePassword(String password) {
//TODO Implement password encryption for wallet
}
public interface Activatable {
void activate();
void deactivate();
}

View File

@ -15,27 +15,33 @@
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
*/
package io.bitsquare.gui.main.account.content.seedwords;
package io.bitsquare.gui;
import io.bitsquare.btc.WalletService;
import io.bitsquare.gui.UIModel;
public abstract class ActivatableWithDelegate<D extends Activatable> extends WithDelegate<D> implements Activatable {
import com.google.inject.Inject;
import java.util.List;
class SeedWordsModel extends UIModel {
private List<String> mnemonicCode;
@Inject
public SeedWordsModel(WalletService walletService) {
if (walletService != null && walletService.getWallet() != null)
mnemonicCode = walletService.getWallet().getKeyChainSeed().getMnemonicCode();
public ActivatableWithDelegate(D delegate) {
super(delegate);
}
List<String> getMnemonicCode() {
return mnemonicCode;
@Override
public final void activate() {
if (delegate != null)
delegate.activate();
doActivate();
}
protected void doActivate() {
}
@Override
public final void deactivate() {
if (delegate != null)
delegate.deactivate();
doDeactivate();
}
protected void doDeactivate() {
}
}

View File

@ -29,7 +29,7 @@ import org.slf4j.LoggerFactory;
* active and awake it at reactivation.
* * @param <T> The PresentationModel used in that class
*/
public class CachedViewCB<T extends PresentationModel> extends ViewCB {
public class CachedViewCB<T extends Activatable> extends ViewCB {
private static final Logger log = LoggerFactory.getLogger(CachedViewCB.class);
protected final T presentationModel;

View File

@ -17,17 +17,5 @@
package io.bitsquare.gui;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class UIModel {
private static final Logger log = LoggerFactory.getLogger(UIModel.class);
public void activate() {
log.trace("Lifecycle: activate " + this.getClass().getSimpleName());
}
public void deactivate() {
log.trace("Lifecycle: deactivate " + this.getClass().getSimpleName());
}
public interface DataModel {
}

View File

@ -1,46 +0,0 @@
/*
* This file is part of Bitsquare.
*
* Bitsquare is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bitsquare is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
*/
package io.bitsquare.gui;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public abstract class PresentationModel<T extends UIModel> {
private static final Logger log = LoggerFactory.getLogger(PresentationModel.class);
protected T model;
public PresentationModel(T model) {
this.model = model;
}
public PresentationModel() {
}
public void activate() {
log.trace("Lifecycle: activate " + this.getClass().getSimpleName());
if (model != null)
model.activate();
}
public void deactivate() {
log.trace("Lifecycle: deactivate " + this.getClass().getSimpleName());
if (model != null)
model.deactivate();
}
}

View File

@ -15,26 +15,7 @@
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
*/
package io.bitsquare.gui.main.account;
import io.bitsquare.gui.UIModel;
import io.bitsquare.user.User;
import com.google.inject.Inject;
class AccountModel extends UIModel {
private final User user;
@Inject
public AccountModel(User user) {
this.user = user;
}
boolean getNeedRegistration() {
return user.getAccountId() == null;
}
package io.bitsquare.gui;
public interface ViewModel {
}

View File

@ -15,23 +15,13 @@
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
*/
package io.bitsquare.gui.main.account.content.password;
package io.bitsquare.gui;
import io.bitsquare.gui.UIModel;
public abstract class WithDelegate<D> {
import com.google.inject.Inject;
protected final D delegate;
class PasswordModel extends UIModel {
@Inject
public PasswordModel() {
protected WithDelegate(D delegate) {
this.delegate = delegate;
}
@SuppressWarnings("EmptyMethod")
void savePassword(String password) {
//TODO Implement password encryption for wallet
}
}

View File

@ -17,19 +17,21 @@
package io.bitsquare.gui.main.account;
import io.bitsquare.gui.PresentationModel;
import io.bitsquare.gui.ViewModel;
import io.bitsquare.user.User;
import com.google.inject.Inject;
class AccountPM extends PresentationModel<AccountModel> {
class AccountPM implements ViewModel {
private final User user;
@Inject
public AccountPM(AccountModel model) {
super(model);
public AccountPM(User user) {
this.user = user;
}
boolean getNeedRegistration() {
return model.getNeedRegistration();
return user.getAccountId() == null;
}
}

View File

@ -36,7 +36,7 @@ import javafx.scene.control.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class AccountViewCB extends CachedViewCB<AccountPM> {
public class AccountViewCB extends CachedViewCB {
private static final Logger log = LoggerFactory.getLogger(AccountViewCB.class);
@ -45,6 +45,7 @@ public class AccountViewCB extends CachedViewCB<AccountPM> {
@FXML Tab accountSettingsTab, arbitratorSettingsTab;
private final AccountPM model;
private final ViewLoader viewLoader;
private final Navigation navigation;
@ -54,8 +55,9 @@ public class AccountViewCB extends CachedViewCB<AccountPM> {
///////////////////////////////////////////////////////////////////////////////////////////
@Inject
private AccountViewCB(AccountPM presentationModel, ViewLoader viewLoader, Navigation navigation) {
super(presentationModel);
private AccountViewCB(AccountPM model, ViewLoader viewLoader, Navigation navigation) {
super();
this.model = model;
this.viewLoader = viewLoader;
this.navigation = navigation;
}
@ -96,7 +98,7 @@ public class AccountViewCB extends CachedViewCB<AccountPM> {
if (navigation.getCurrentItems().length == 2 &&
navigation.getCurrentItems()[1] == Navigation.Item.ACCOUNT) {
if (presentationModel.getNeedRegistration()) {
if (model.getNeedRegistration()) {
navigation.navigationTo(Navigation.Item.MAIN, Navigation.Item.ACCOUNT,
Navigation.Item.ACCOUNT_SETUP);
}

View File

@ -17,7 +17,7 @@
package io.bitsquare.gui.main.account.content.changepassword;
import io.bitsquare.gui.PresentationModel;
import io.bitsquare.gui.ViewModel;
import io.bitsquare.gui.util.validation.InputValidator;
import io.bitsquare.gui.util.validation.PasswordValidator;
@ -28,7 +28,7 @@ import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
class ChangePasswordPM extends PresentationModel<ChangePasswordModel> {
class ChangePasswordPM implements ViewModel {
private final PasswordValidator passwordValidator;
@ -40,8 +40,7 @@ class ChangePasswordPM extends PresentationModel<ChangePasswordModel> {
@Inject
public ChangePasswordPM(ChangePasswordModel model, PasswordValidator passwordValidator) {
super(model);
public ChangePasswordPM(PasswordValidator passwordValidator) {
this.passwordValidator = passwordValidator;
passwordField.addListener((ov) -> saveButtonDisabled.set(!validate()));
@ -51,12 +50,16 @@ class ChangePasswordPM extends PresentationModel<ChangePasswordModel> {
boolean requestSavePassword() {
if (validate()) {
model.savePassword(passwordField.get());
savePassword(passwordField.get());
return true;
}
return false;
}
void savePassword(String password) {
//TODO Implement password encryption for wallet
}
String getErrorMessage() {
return errorMessage;
}

View File

@ -17,7 +17,7 @@
package io.bitsquare.gui.main.account.content.changepassword;
import io.bitsquare.gui.CachedViewCB;
import io.bitsquare.gui.ViewCB;
import io.bitsquare.gui.main.account.MultiStepNavigation;
import io.bitsquare.gui.main.account.content.ContextAware;
import io.bitsquare.gui.main.help.Help;
@ -36,10 +36,12 @@ import javafx.scene.layout.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class ChangePasswordViewCB extends CachedViewCB<ChangePasswordPM> implements ContextAware {
public class ChangePasswordViewCB extends ViewCB implements ContextAware {
private static final Logger log = LoggerFactory.getLogger(ChangePasswordViewCB.class);
private final ChangePasswordPM model;
@FXML HBox buttonsHBox;
@FXML Button saveButton, skipButton;
@FXML PasswordField oldPasswordField, passwordField, repeatedPasswordField;
@ -50,8 +52,8 @@ public class ChangePasswordViewCB extends CachedViewCB<ChangePasswordPM> impleme
///////////////////////////////////////////////////////////////////////////////////////////
@Inject
private ChangePasswordViewCB(ChangePasswordPM presentationModel) {
super(presentationModel);
private ChangePasswordViewCB(ChangePasswordPM model) {
this.model = model;
}
@ -63,31 +65,12 @@ public class ChangePasswordViewCB extends CachedViewCB<ChangePasswordPM> impleme
public void initialize(URL url, ResourceBundle rb) {
super.initialize(url, rb);
passwordField.textProperty().bindBidirectional(presentationModel.passwordField);
repeatedPasswordField.textProperty().bindBidirectional(presentationModel.repeatedPasswordField);
passwordField.textProperty().bindBidirectional(model.passwordField);
repeatedPasswordField.textProperty().bindBidirectional(model.repeatedPasswordField);
saveButton.disableProperty().bind(presentationModel.saveButtonDisabled);
saveButton.disableProperty().bind(model.saveButtonDisabled);
}
@SuppressWarnings("EmptyMethod")
@Override
public void activate() {
super.activate();
}
@SuppressWarnings("EmptyMethod")
@Override
public void deactivate() {
super.deactivate();
}
@SuppressWarnings("EmptyMethod")
@Override
public void terminate() {
super.terminate();
}
///////////////////////////////////////////////////////////////////////////////////////////
// ContextAware implementation
///////////////////////////////////////////////////////////////////////////////////////////
@ -105,13 +88,13 @@ public class ChangePasswordViewCB extends CachedViewCB<ChangePasswordPM> impleme
@FXML
private void onSaved() {
boolean result = presentationModel.requestSavePassword();
boolean result = model.requestSavePassword();
if (result) {
if (parent instanceof MultiStepNavigation)
((MultiStepNavigation) parent).nextStep(this);
}
else {
log.debug(presentationModel.getErrorMessage()); // TODO use validating TF
log.debug(model.getErrorMessage()); // TODO use validating TF
}
}

View File

@ -20,7 +20,8 @@ package io.bitsquare.gui.main.account.content.fiat;
import io.bitsquare.account.AccountSettings;
import io.bitsquare.bank.BankAccount;
import io.bitsquare.bank.BankAccountType;
import io.bitsquare.gui.UIModel;
import io.bitsquare.gui.Activatable;
import io.bitsquare.gui.DataModel;
import io.bitsquare.locale.Country;
import io.bitsquare.locale.CountryUtil;
import io.bitsquare.locale.CurrencyUtil;
@ -41,7 +42,7 @@ import javafx.beans.property.StringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
class FiatAccountModel extends UIModel {
class FiatAccountModel implements Activatable, DataModel {
private final User user;
private final AccountSettings accountSettings;
@ -76,11 +77,14 @@ class FiatAccountModel extends UIModel {
@Override
public void activate() {
super.activate();
allBankAccounts.setAll(user.getBankAccounts());
}
@Override
public void deactivate() {
// no-op
}
void saveBankAccount() {
BankAccount bankAccount = new BankAccount(type.get(),

View File

@ -19,7 +19,8 @@ package io.bitsquare.gui.main.account.content.fiat;
import io.bitsquare.bank.BankAccount;
import io.bitsquare.bank.BankAccountType;
import io.bitsquare.gui.PresentationModel;
import io.bitsquare.gui.ActivatableWithDelegate;
import io.bitsquare.gui.ViewModel;
import io.bitsquare.gui.util.validation.BankAccountNumberValidator;
import io.bitsquare.gui.util.validation.InputValidator;
import io.bitsquare.locale.BSResources;
@ -40,7 +41,7 @@ import javafx.collections.ListChangeListener;
import javafx.collections.ObservableList;
import javafx.util.StringConverter;
class FiatAccountPM extends PresentationModel<FiatAccountModel> {
class FiatAccountPM extends ActivatableWithDelegate<FiatAccountModel> implements ViewModel {
private final BankAccountNumberValidator bankAccountNumberValidator;
@ -85,10 +86,8 @@ class FiatAccountPM extends PresentationModel<FiatAccountModel> {
}
@Override
public void activate() {
super.activate();
model.allBankAccounts.addListener((ListChangeListener<BankAccount>) change -> applyAllBankAccounts());
public void doActivate() {
delegate.allBankAccounts.addListener((ListChangeListener<BankAccount>) change -> applyAllBankAccounts());
applyAllBankAccounts();
}
@ -96,21 +95,21 @@ class FiatAccountPM extends PresentationModel<FiatAccountModel> {
InputValidator.ValidationResult requestSaveBankAccount() {
InputValidator.ValidationResult result = validateInput();
if (result.isValid) {
model.saveBankAccount();
delegate.saveBankAccount();
}
return result;
}
void removeBankAccount() {
model.removeBankAccount();
delegate.removeBankAccount();
}
void addCountryToAcceptedCountriesList() {
model.addCountryToAcceptedCountriesList();
delegate.addCountryToAcceptedCountriesList();
}
void selectBankAccount(BankAccount bankAccount) {
model.selectBankAccount(bankAccount);
delegate.selectBankAccount(bankAccount);
}
@ -188,27 +187,27 @@ class FiatAccountPM extends PresentationModel<FiatAccountModel> {
ObservableList<BankAccountType> getAllTypes() {
return model.allTypes;
return delegate.allTypes;
}
ObservableList<BankAccount> getAllBankAccounts() {
return model.allBankAccounts;
return delegate.allBankAccounts;
}
ObservableList<Currency> getAllCurrencies() {
return model.allCurrencies;
return delegate.allCurrencies;
}
ObservableList<Region> getAllRegions() {
return model.allRegions;
return delegate.allRegions;
}
BooleanProperty getCountryNotInAcceptedCountriesList() {
return model.countryNotInAcceptedCountriesList;
return delegate.countryNotInAcceptedCountriesList;
}
ObservableList<Country> getAllCountriesFor(Region selectedRegion) {
return model.getAllCountriesFor(selectedRegion);
return delegate.getAllCountriesFor(selectedRegion);
}
BankAccountNumberValidator getBankAccountNumberValidator() {
@ -217,23 +216,23 @@ class FiatAccountPM extends PresentationModel<FiatAccountModel> {
void setType(BankAccountType type) {
model.setType(type);
delegate.setType(type);
validateInput();
}
void setCountry(Country country) {
model.setCountry(country);
delegate.setCountry(country);
validateInput();
}
void setCurrency(Currency currency) {
model.setCurrency(currency);
delegate.setCurrency(currency);
validateInput();
}
private void applyAllBankAccounts() {
if (model.allBankAccounts.isEmpty()) {
if (delegate.allBankAccounts.isEmpty()) {
selectionPrompt.set("No bank account available");
selectionDisable.set(true);
}
@ -244,23 +243,23 @@ class FiatAccountPM extends PresentationModel<FiatAccountModel> {
}
private InputValidator.ValidationResult validateInput() {
InputValidator.ValidationResult result = bankAccountNumberValidator.validate(model.title.get());
InputValidator.ValidationResult result = bankAccountNumberValidator.validate(delegate.title.get());
if (result.isValid) {
result = bankAccountNumberValidator.validate(model.holderName.get());
result = bankAccountNumberValidator.validate(delegate.holderName.get());
if (result.isValid) {
result = bankAccountNumberValidator.validate(model.primaryID.get());
result = bankAccountNumberValidator.validate(delegate.primaryID.get());
if (result.isValid) {
result = bankAccountNumberValidator.validate(model.secondaryID.get());
result = bankAccountNumberValidator.validate(delegate.secondaryID.get());
if (result.isValid) {
if (model.currency.get() == null)
if (delegate.currency.get() == null)
result = new InputValidator.ValidationResult(false,
"You have not selected a currency");
if (result.isValid) {
if (model.country.get() == null)
if (delegate.country.get() == null)
result = new InputValidator.ValidationResult(false,
"You have not selected a country of the payments account");
if (result.isValid) {
if (model.type.get() == null)
if (delegate.type.get() == null)
result = new InputValidator.ValidationResult(false,
"You have not selected a payments method");
}

View File

@ -22,7 +22,8 @@ import io.bitsquare.arbitrator.Arbitrator;
import io.bitsquare.arbitrator.Reputation;
import io.bitsquare.bank.BankAccount;
import io.bitsquare.bank.BankAccountType;
import io.bitsquare.gui.UIModel;
import io.bitsquare.gui.Activatable;
import io.bitsquare.gui.DataModel;
import io.bitsquare.locale.Country;
import io.bitsquare.locale.CountryUtil;
import io.bitsquare.locale.CurrencyUtil;
@ -51,7 +52,7 @@ import javafx.beans.property.StringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
class IrcAccountModel extends UIModel {
class IrcAccountModel implements Activatable, DataModel {
private final User user;
private final AccountSettings accountSettings;
@ -82,10 +83,14 @@ class IrcAccountModel extends UIModel {
@Override
public void activate() {
super.activate();
allBankAccounts.setAll(user.getBankAccounts());
}
@Override
public void deactivate() {
// no-op
}
void saveBankAccount() {
BankAccount bankAccount = new BankAccount(type.get(),
currency.get(),

View File

@ -19,7 +19,8 @@ package io.bitsquare.gui.main.account.content.irc;
import io.bitsquare.bank.BankAccount;
import io.bitsquare.bank.BankAccountType;
import io.bitsquare.gui.PresentationModel;
import io.bitsquare.gui.ActivatableWithDelegate;
import io.bitsquare.gui.ViewModel;
import io.bitsquare.gui.util.validation.BankAccountNumberValidator;
import io.bitsquare.gui.util.validation.InputValidator;
import io.bitsquare.locale.BSResources;
@ -37,7 +38,7 @@ import javafx.beans.property.StringProperty;
import javafx.collections.ObservableList;
import javafx.util.StringConverter;
class IrcAccountPM extends PresentationModel<IrcAccountModel> {
class IrcAccountPM extends ActivatableWithDelegate<IrcAccountModel> implements ViewModel {
private final InputValidator nickNameValidator;
@ -64,13 +65,13 @@ class IrcAccountPM extends PresentationModel<IrcAccountModel> {
InputValidator.ValidationResult requestSaveBankAccount() {
InputValidator.ValidationResult result = validateInput();
if (result.isValid) {
model.saveBankAccount();
delegate.saveBankAccount();
}
return result;
}
ObservableList<BankAccount> getAllBankAccounts() {
return model.allBankAccounts;
return delegate.allBankAccounts;
}
StringConverter<BankAccountType> getTypesConverter() {
@ -107,11 +108,11 @@ class IrcAccountPM extends PresentationModel<IrcAccountModel> {
ObservableList<BankAccountType> getAllTypes() {
return model.allTypes;
return delegate.allTypes;
}
ObservableList<Currency> getAllCurrencies() {
return model.allCurrencies;
return delegate.allCurrencies;
}
InputValidator getNickNameValidator() {
@ -120,24 +121,24 @@ class IrcAccountPM extends PresentationModel<IrcAccountModel> {
void setType(BankAccountType type) {
model.setType(type);
delegate.setType(type);
validateInput();
}
void setCurrency(Currency currency) {
model.setCurrency(currency);
delegate.setCurrency(currency);
validateInput();
}
private InputValidator.ValidationResult validateInput() {
InputValidator.ValidationResult result = nickNameValidator.validate(model.nickName.get());
if (model.currency.get() == null)
InputValidator.ValidationResult result = nickNameValidator.validate(delegate.nickName.get());
if (delegate.currency.get() == null)
result = new InputValidator.ValidationResult(false,
"You have not selected a currency");
if (result.isValid) {
if (model.type.get() == null)
if (delegate.type.get() == null)
result = new InputValidator.ValidationResult(false,
"You have not selected a payments method");
}

View File

@ -17,7 +17,7 @@
package io.bitsquare.gui.main.account.content.password;
import io.bitsquare.gui.PresentationModel;
import io.bitsquare.gui.ViewModel;
import io.bitsquare.gui.util.validation.InputValidator;
import io.bitsquare.gui.util.validation.PasswordValidator;
@ -28,7 +28,7 @@ import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
class PasswordPM extends PresentationModel<PasswordModel> {
class PasswordPM implements ViewModel {
private final PasswordValidator passwordValidator;
@ -40,8 +40,7 @@ class PasswordPM extends PresentationModel<PasswordModel> {
@Inject
public PasswordPM(PasswordModel model, PasswordValidator passwordValidator) {
super(model);
public PasswordPM(PasswordValidator passwordValidator) {
this.passwordValidator = passwordValidator;
passwordField.addListener((ov) -> saveButtonDisabled.set(!validate()));
@ -51,12 +50,16 @@ class PasswordPM extends PresentationModel<PasswordModel> {
boolean requestSavePassword() {
if (validate()) {
model.savePassword(passwordField.get());
savePassword(passwordField.get());
return true;
}
return false;
}
void savePassword(String password) {
//TODO Implement password encryption for wallet
}
String getErrorMessage() {
return errorMessage;
}

View File

@ -17,7 +17,7 @@
package io.bitsquare.gui.main.account.content.password;
import io.bitsquare.gui.CachedViewCB;
import io.bitsquare.gui.ViewCB;
import io.bitsquare.gui.main.account.MultiStepNavigation;
import io.bitsquare.gui.main.account.content.ContextAware;
import io.bitsquare.gui.main.help.Help;
@ -36,10 +36,12 @@ import javafx.scene.layout.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class PasswordViewCB extends CachedViewCB<PasswordPM> implements ContextAware {
public class PasswordViewCB extends ViewCB implements ContextAware {
private static final Logger log = LoggerFactory.getLogger(PasswordViewCB.class);
private final PasswordPM model;
@FXML HBox buttonsHBox;
@FXML Button saveButton, skipButton;
@FXML PasswordField oldPasswordField, passwordField, repeatedPasswordField;
@ -50,8 +52,8 @@ public class PasswordViewCB extends CachedViewCB<PasswordPM> implements ContextA
///////////////////////////////////////////////////////////////////////////////////////////
@Inject
private PasswordViewCB(PasswordPM presentationModel) {
super(presentationModel);
private PasswordViewCB(PasswordPM model) {
this.model = model;
}
@ -63,28 +65,10 @@ public class PasswordViewCB extends CachedViewCB<PasswordPM> implements ContextA
public void initialize(URL url, ResourceBundle rb) {
super.initialize(url, rb);
passwordField.textProperty().bindBidirectional(presentationModel.passwordField);
repeatedPasswordField.textProperty().bindBidirectional(presentationModel.repeatedPasswordField);
passwordField.textProperty().bindBidirectional(model.passwordField);
repeatedPasswordField.textProperty().bindBidirectional(model.repeatedPasswordField);
saveButton.disableProperty().bind(presentationModel.saveButtonDisabled);
}
@SuppressWarnings("EmptyMethod")
@Override
public void activate() {
super.activate();
}
@SuppressWarnings("EmptyMethod")
@Override
public void deactivate() {
super.deactivate();
}
@SuppressWarnings("EmptyMethod")
@Override
public void terminate() {
super.terminate();
saveButton.disableProperty().bind(model.saveButtonDisabled);
}
@ -105,14 +89,14 @@ public class PasswordViewCB extends CachedViewCB<PasswordPM> implements ContextA
@FXML
private void onSaved() {
boolean result = presentationModel.requestSavePassword();
boolean result = model.requestSavePassword();
if (result) {
if (parent instanceof MultiStepNavigation)
((MultiStepNavigation) parent).nextStep(this);
}
else {
// TODO use validating passwordTF
log.debug(presentationModel.getErrorMessage());
log.debug(model.getErrorMessage());
}
}

View File

@ -21,7 +21,7 @@ import io.bitsquare.btc.AddressEntry;
import io.bitsquare.btc.FeePolicy;
import io.bitsquare.btc.WalletService;
import io.bitsquare.btc.listeners.BalanceListener;
import io.bitsquare.gui.UIModel;
import io.bitsquare.gui.DataModel;
import io.bitsquare.persistence.Persistence;
import io.bitsquare.user.User;
@ -45,7 +45,7 @@ import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
class RegistrationModel extends UIModel {
class RegistrationModel implements DataModel {
private static final Logger log = LoggerFactory.getLogger(RegistrationModel.class);
private final WalletService walletService;

View File

@ -18,7 +18,8 @@
package io.bitsquare.gui.main.account.content.registration;
import io.bitsquare.btc.WalletService;
import io.bitsquare.gui.PresentationModel;
import io.bitsquare.gui.ViewModel;
import io.bitsquare.gui.WithDelegate;
import io.bitsquare.gui.util.BSFormatter;
import io.bitsquare.locale.BSResources;
@ -35,7 +36,7 @@ import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
class RegistrationPM extends PresentationModel<RegistrationModel> {
class RegistrationPM extends WithDelegate<RegistrationModel> implements ViewModel {
final BooleanProperty isPayButtonDisabled = new SimpleBooleanProperty(true);
final StringProperty requestPlaceOfferErrorMessage = new SimpleStringProperty();
@ -48,27 +49,27 @@ class RegistrationPM extends PresentationModel<RegistrationModel> {
@Inject
public RegistrationPM(RegistrationModel model, BSFormatter formatter) {
super(model);
public RegistrationPM(RegistrationModel delegate, BSFormatter formatter) {
super(delegate);
this.formatter = formatter;
if (model.getAddressEntry() != null) {
address.set(model.getAddressEntry().getAddress());
if (delegate.getAddressEntry() != null) {
address.set(delegate.getAddressEntry().getAddress());
}
model.isWalletFunded.addListener((ov, oldValue, newValue) -> {
delegate.isWalletFunded.addListener((ov, oldValue, newValue) -> {
if (newValue)
validateInput();
});
validateInput();
model.payFeeSuccess.addListener((ov, oldValue, newValue) -> {
delegate.payFeeSuccess.addListener((ov, oldValue, newValue) -> {
isPayButtonDisabled.set(newValue);
showTransactionPublishedScreen.set(newValue);
isPaymentSpinnerVisible.set(false);
});
model.payFeeErrorMessage.addListener((ov, oldValue, newValue) -> {
delegate.payFeeErrorMessage.addListener((ov, oldValue, newValue) -> {
if (newValue != null) {
requestPlaceOfferErrorMessage.set(newValue);
isPaymentSpinnerVisible.set(false);
@ -77,18 +78,18 @@ class RegistrationPM extends PresentationModel<RegistrationModel> {
}
void payFee() {
model.payFeeErrorMessage.set(null);
model.payFeeSuccess.set(false);
delegate.payFeeErrorMessage.set(null);
delegate.payFeeSuccess.set(false);
isPayButtonDisabled.set(true);
isPaymentSpinnerVisible.set(true);
model.payFee();
delegate.payFee();
}
WalletService getWalletService() {
return model.getWalletService();
return delegate.getWalletService();
}
BSFormatter getFormatter() {
@ -96,11 +97,11 @@ class RegistrationPM extends PresentationModel<RegistrationModel> {
}
Coin getFeeAsCoin() {
return model.getFeeAsCoin();
return delegate.getFeeAsCoin();
}
String getAddressAsString() {
return model.getAddressEntry() != null ? model.getAddressEntry().getAddress().toString() : "";
return delegate.getAddressEntry() != null ? delegate.getAddressEntry().getAddress().toString() : "";
}
String getPaymentLabel() {
@ -108,16 +109,16 @@ class RegistrationPM extends PresentationModel<RegistrationModel> {
}
String getFeeAsString() {
return formatter.formatCoinWithCode(model.getFeeAsCoin());
return formatter.formatCoinWithCode(delegate.getFeeAsCoin());
}
String getTransactionId() {
return model.getTransactionId();
return delegate.getTransactionId();
}
private void validateInput() {
isPayButtonDisabled.set(!(model.isWalletFunded.get()));
isPayButtonDisabled.set(!(delegate.isWalletFunded.get()));
}

View File

@ -17,8 +17,8 @@
package io.bitsquare.gui.main.account.content.registration;
import io.bitsquare.gui.CachedViewCB;
import io.bitsquare.gui.OverlayManager;
import io.bitsquare.gui.ViewCB;
import io.bitsquare.gui.components.AddressTextField;
import io.bitsquare.gui.components.BalanceTextField;
import io.bitsquare.gui.components.Popups;
@ -48,11 +48,12 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class RegistrationViewCB extends CachedViewCB<RegistrationPM> implements ContextAware {
public class RegistrationViewCB extends ViewCB implements ContextAware {
private static final Logger log = LoggerFactory.getLogger(RegistrationViewCB.class);
private final OverlayManager overlayManager;
private final RegistrationPM model;
@FXML TextField feeTextField;
@FXML AddressTextField addressTextField;
@ -67,8 +68,8 @@ public class RegistrationViewCB extends CachedViewCB<RegistrationPM> implements
///////////////////////////////////////////////////////////////////////////////////////////
@Inject
private RegistrationViewCB(RegistrationPM presentationModel, OverlayManager overlayManager) {
super(presentationModel);
private RegistrationViewCB(RegistrationPM model, OverlayManager overlayManager) {
this.model = model;
this.overlayManager = overlayManager;
}
@ -81,20 +82,20 @@ public class RegistrationViewCB extends CachedViewCB<RegistrationPM> implements
public void initialize(URL url, ResourceBundle rb) {
super.initialize(url, rb);
feeTextField.setText(presentationModel.getFeeAsString());
addressTextField.setAmountAsCoin(presentationModel.getFeeAsCoin());
addressTextField.setPaymentLabel(presentationModel.getPaymentLabel());
addressTextField.setAddress(presentationModel.getAddressAsString());
feeTextField.setText(model.getFeeAsString());
addressTextField.setAmountAsCoin(model.getFeeAsCoin());
addressTextField.setPaymentLabel(model.getPaymentLabel());
addressTextField.setAddress(model.getAddressAsString());
// TODO find better solution
addressTextField.setOverlayManager(overlayManager);
balanceTextField.setup(presentationModel.getWalletService(), presentationModel.address.get(),
presentationModel.getFormatter());
balanceTextField.setup(model.getWalletService(), model.address.get(),
model.getFormatter());
payButton.disableProperty().bind(presentationModel.isPayButtonDisabled);
payButton.disableProperty().bind(model.isPayButtonDisabled);
presentationModel.requestPlaceOfferErrorMessage.addListener((o, oldValue, newValue) -> {
model.requestPlaceOfferErrorMessage.addListener((o, oldValue, newValue) -> {
if (newValue != null) {
Popups.openErrorPopup(BSResources.get("shared.error"),
BSResources.get("An error occurred when paying the registration fee"),
@ -102,14 +103,14 @@ public class RegistrationViewCB extends CachedViewCB<RegistrationPM> implements
}
});
paymentSpinnerInfoLabel.visibleProperty().bind(presentationModel.isPaymentSpinnerVisible);
paymentSpinnerInfoLabel.visibleProperty().bind(model.isPaymentSpinnerVisible);
presentationModel.isPaymentSpinnerVisible.addListener((ov, oldValue, newValue) -> {
model.isPaymentSpinnerVisible.addListener((ov, oldValue, newValue) -> {
paymentSpinner.setProgress(newValue ? -1 : 0);
paymentSpinner.setVisible(newValue);
});
presentationModel.showTransactionPublishedScreen.addListener((o, oldValue, newValue) -> {
model.showTransactionPublishedScreen.addListener((o, oldValue, newValue) -> {
if (newValue) {
overlayManager.blurContent();
@ -144,24 +145,6 @@ public class RegistrationViewCB extends CachedViewCB<RegistrationPM> implements
});
}
@SuppressWarnings("EmptyMethod")
@Override
public void activate() {
super.activate();
}
@SuppressWarnings("EmptyMethod")
@Override
public void deactivate() {
super.deactivate();
}
@SuppressWarnings("EmptyMethod")
@Override
public void terminate() {
super.terminate();
}
///////////////////////////////////////////////////////////////////////////////////////////
// ContextAware implementation
@ -181,7 +164,7 @@ public class RegistrationViewCB extends CachedViewCB<RegistrationPM> implements
@FXML
private void onPayFee() {
presentationModel.payFee();
model.payFee();
}
@FXML

View File

@ -20,7 +20,8 @@ package io.bitsquare.gui.main.account.content.restrictions;
import io.bitsquare.account.AccountSettings;
import io.bitsquare.arbitrator.Arbitrator;
import io.bitsquare.arbitrator.Reputation;
import io.bitsquare.gui.UIModel;
import io.bitsquare.gui.Activatable;
import io.bitsquare.gui.DataModel;
import io.bitsquare.locale.Country;
import io.bitsquare.locale.CountryUtil;
import io.bitsquare.locale.LanguageUtil;
@ -43,7 +44,7 @@ import java.util.Locale;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
class RestrictionsModel extends UIModel {
class RestrictionsModel implements Activatable, DataModel {
private final User user;
private final AccountSettings accountSettings;
@ -85,12 +86,16 @@ class RestrictionsModel extends UIModel {
@Override
public void activate() {
super.activate();
languageList.setAll(accountSettings.getAcceptedLanguageLocales());
countryList.setAll(accountSettings.getAcceptedCountries());
arbitratorList.setAll(accountSettings.getAcceptedArbitrators());
}
@Override
public void deactivate() {
// no-op
}
ObservableList<Country> getAllCountriesFor(Region selectedRegion) {
return FXCollections.observableArrayList(CountryUtil.getAllCountriesFor(selectedRegion));
}

View File

@ -18,7 +18,8 @@
package io.bitsquare.gui.main.account.content.restrictions;
import io.bitsquare.arbitrator.Arbitrator;
import io.bitsquare.gui.PresentationModel;
import io.bitsquare.gui.ActivatableWithDelegate;
import io.bitsquare.gui.ViewModel;
import io.bitsquare.locale.Country;
import io.bitsquare.locale.Region;
@ -30,7 +31,7 @@ import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.collections.ObservableList;
class RestrictionsPM extends PresentationModel<RestrictionsModel> {
class RestrictionsPM extends ActivatableWithDelegate<RestrictionsModel> implements ViewModel {
final BooleanProperty doneButtonDisable = new SimpleBooleanProperty(true);
@ -42,77 +43,75 @@ class RestrictionsPM extends PresentationModel<RestrictionsModel> {
@Override
public void activate() {
super.activate();
public void doActivate() {
updateDoneButtonDisableState();
}
void addLanguage(Locale locale) {
model.addLanguage(locale);
delegate.addLanguage(locale);
updateDoneButtonDisableState();
}
void removeLanguage(Locale locale) {
model.removeLanguage(locale);
delegate.removeLanguage(locale);
updateDoneButtonDisableState();
}
void addCountry(Country country) {
model.addCountry(country);
delegate.addCountry(country);
updateDoneButtonDisableState();
}
void removeCountry(Country country) {
model.removeCountry(country);
delegate.removeCountry(country);
updateDoneButtonDisableState();
}
void removeArbitrator(Arbitrator arbitrator) {
model.removeArbitrator(arbitrator);
delegate.removeArbitrator(arbitrator);
updateDoneButtonDisableState();
}
void updateArbitratorList() {
model.updateArbitratorList();
delegate.updateArbitratorList();
updateDoneButtonDisableState();
}
ObservableList<Country> getListWithAllEuroCountries() {
return model.getListWithAllEuroCountries();
return delegate.getListWithAllEuroCountries();
}
ObservableList<Country> getAllCountriesFor(Region selectedRegion) {
return model.getAllCountriesFor(selectedRegion);
return delegate.getAllCountriesFor(selectedRegion);
}
ObservableList<Locale> getLanguageList() {
return model.languageList;
return delegate.languageList;
}
ObservableList<Region> getAllRegions() {
return model.allRegions;
return delegate.allRegions;
}
ObservableList<Locale> getAllLanguages() {
return model.allLanguages;
return delegate.allLanguages;
}
ObservableList<Country> getCountryList() {
return model.countryList;
return delegate.countryList;
}
ObservableList<Arbitrator> getArbitratorList() {
return model.arbitratorList;
return delegate.arbitratorList;
}
//TODO Revert size() > -1 to 0(2 later). For mock testing disabled arbitratorList test
private void updateDoneButtonDisableState() {
boolean isValid = model.languageList != null && model.languageList.size() > 0 &&
model.countryList != null && model.countryList.size() > 0 &&
model.arbitratorList != null && model.arbitratorList.size() > -1;
boolean isValid = delegate.languageList != null && delegate.languageList.size() > 0 &&
delegate.countryList != null && delegate.countryList.size() > 0 &&
delegate.arbitratorList != null && delegate.arbitratorList.size() > -1;
doneButtonDisable.set(!isValid);
}

View File

@ -17,24 +17,28 @@
package io.bitsquare.gui.main.account.content.seedwords;
import io.bitsquare.gui.PresentationModel;
import io.bitsquare.btc.WalletService;
import io.bitsquare.gui.ViewModel;
import io.bitsquare.gui.util.BSFormatter;
import com.google.inject.Inject;
import java.util.List;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
class SeedWordsPM extends PresentationModel<SeedWordsModel> {
class SeedWordsPM implements ViewModel {
final StringProperty seedWords = new SimpleStringProperty();
@Inject
public SeedWordsPM(SeedWordsModel model, BSFormatter formatter) {
super(model);
if (model.getMnemonicCode() != null)
seedWords.set(formatter.mnemonicCodeToString(model.getMnemonicCode()));
public SeedWordsPM(WalletService walletService, BSFormatter formatter) {
if (walletService.getWallet() != null) {
List<String> mnemonicCode = walletService.getWallet().getKeyChainSeed().getMnemonicCode();
if (mnemonicCode != null) {
seedWords.set(formatter.mnemonicCodeToString(mnemonicCode));
}
}
}
}

View File

@ -17,7 +17,7 @@
package io.bitsquare.gui.main.account.content.seedwords;
import io.bitsquare.gui.CachedViewCB;
import io.bitsquare.gui.ViewCB;
import io.bitsquare.gui.main.account.MultiStepNavigation;
import io.bitsquare.gui.main.account.content.ContextAware;
import io.bitsquare.gui.main.help.Help;
@ -36,21 +36,23 @@ import javafx.scene.layout.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class SeedWordsViewCB extends CachedViewCB<SeedWordsPM> implements ContextAware {
public class SeedWordsViewCB extends ViewCB implements ContextAware {
private static final Logger log = LoggerFactory.getLogger(SeedWordsViewCB.class);
@FXML Button completedButton;
@FXML TextArea seedWordsTextArea;
private final SeedWordsPM model;
///////////////////////////////////////////////////////////////////////////////////////////
// Constructor
///////////////////////////////////////////////////////////////////////////////////////////
@Inject
private SeedWordsViewCB(SeedWordsPM presentationModel) {
super(presentationModel);
private SeedWordsViewCB(SeedWordsPM model) {
this.model = model;
}
@ -62,25 +64,7 @@ public class SeedWordsViewCB extends CachedViewCB<SeedWordsPM> implements Contex
public void initialize(URL url, ResourceBundle rb) {
super.initialize(url, rb);
seedWordsTextArea.setText(presentationModel.seedWords.get());
}
@SuppressWarnings("EmptyMethod")
@Override
public void activate() {
super.activate();
}
@SuppressWarnings("EmptyMethod")
@Override
public void deactivate() {
super.deactivate();
}
@SuppressWarnings("EmptyMethod")
@Override
public void terminate() {
super.terminate();
seedWordsTextArea.setText(model.seedWords.get());
}

View File

@ -19,7 +19,6 @@ package io.bitsquare.gui.main.account.settings;
import io.bitsquare.gui.CachedViewCB;
import io.bitsquare.gui.Navigation;
import io.bitsquare.gui.PresentationModel;
import io.bitsquare.gui.ViewCB;
import io.bitsquare.gui.ViewLoader;
import io.bitsquare.gui.main.account.content.ContextAware;

View File

@ -18,7 +18,6 @@
package io.bitsquare.gui.main.account.setup;
import io.bitsquare.gui.Navigation;
import io.bitsquare.gui.PresentationModel;
import io.bitsquare.gui.ViewCB;
import io.bitsquare.gui.ViewLoader;
import io.bitsquare.gui.main.account.MultiStepNavigation;
@ -68,7 +67,6 @@ public class AccountSetupViewCB extends ViewCB implements MultiStepNavigation {
@Inject
private AccountSetupViewCB(ViewLoader viewLoader, Navigation navigation) {
super();
this.viewLoader = viewLoader;
this.navigation = navigation;
}

View File

@ -17,7 +17,8 @@
package io.bitsquare.gui.main.portfolio.closed;
import io.bitsquare.gui.UIModel;
import io.bitsquare.gui.Activatable;
import io.bitsquare.gui.DataModel;
import io.bitsquare.offer.Direction;
import io.bitsquare.offer.Offer;
import io.bitsquare.trade.Trade;
@ -30,7 +31,7 @@ import javafx.collections.FXCollections;
import javafx.collections.MapChangeListener;
import javafx.collections.ObservableList;
class ClosedTradesModel extends UIModel {
class ClosedTradesModel implements Activatable, DataModel {
private final TradeManager tradeManager;
private final User user;
@ -54,8 +55,6 @@ class ClosedTradesModel extends UIModel {
@Override
public void activate() {
super.activate();
list.clear();
tradeManager.getClosedTrades().values().stream()
.forEach(e -> list.add(new ClosedTradesListItem(e)));
@ -67,8 +66,6 @@ class ClosedTradesModel extends UIModel {
@Override
public void deactivate() {
super.deactivate();
tradeManager.getClosedTrades().removeListener(mapChangeListener);
}

View File

@ -17,14 +17,15 @@
package io.bitsquare.gui.main.portfolio.closed;
import io.bitsquare.gui.PresentationModel;
import io.bitsquare.gui.ActivatableWithDelegate;
import io.bitsquare.gui.ViewModel;
import io.bitsquare.gui.util.BSFormatter;
import com.google.inject.Inject;
import javafx.collections.ObservableList;
class ClosedTradesPM extends PresentationModel<ClosedTradesModel> {
class ClosedTradesPM extends ActivatableWithDelegate<ClosedTradesModel> implements ViewModel {
private final BSFormatter formatter;
@ -37,7 +38,7 @@ class ClosedTradesPM extends PresentationModel<ClosedTradesModel> {
}
public ObservableList<ClosedTradesListItem> getList() {
return model.getList();
return delegate.getList();
}
String getTradeId(ClosedTradesListItem item) {
@ -57,7 +58,7 @@ class ClosedTradesPM extends PresentationModel<ClosedTradesModel> {
}
String getDirectionLabel(ClosedTradesListItem item) {
return (item != null) ? formatter.formatDirection(model.getDirection(item.getTrade().getOffer())) : "";
return (item != null) ? formatter.formatDirection(delegate.getDirection(item.getTrade().getOffer())) : "";
}
String getDate(ClosedTradesListItem item) {

View File

@ -17,7 +17,8 @@
package io.bitsquare.gui.main.portfolio.offer;
import io.bitsquare.gui.UIModel;
import io.bitsquare.gui.Activatable;
import io.bitsquare.gui.DataModel;
import io.bitsquare.offer.Direction;
import io.bitsquare.offer.Offer;
import io.bitsquare.trade.TradeManager;
@ -31,7 +32,7 @@ import javafx.collections.FXCollections;
import javafx.collections.MapChangeListener;
import javafx.collections.ObservableList;
class OffersModel extends UIModel {
class OffersModel implements Activatable, DataModel {
private final TradeManager tradeManager;
private final User user;
@ -55,8 +56,6 @@ class OffersModel extends UIModel {
@Override
public void activate() {
super.activate();
list.clear();
list.addAll(tradeManager.getOffers().values().stream().map(OfferListItem::new).collect(Collectors.toList()));
@ -68,8 +67,6 @@ class OffersModel extends UIModel {
@Override
public void deactivate() {
super.deactivate();
tradeManager.getOffers().removeListener(offerMapChangeListener);
}

View File

@ -17,14 +17,15 @@
package io.bitsquare.gui.main.portfolio.offer;
import io.bitsquare.gui.PresentationModel;
import io.bitsquare.gui.ActivatableWithDelegate;
import io.bitsquare.gui.ViewModel;
import io.bitsquare.gui.util.BSFormatter;
import com.google.inject.Inject;
import javafx.collections.ObservableList;
class OffersPM extends PresentationModel<OffersModel> {
class OffersPM extends ActivatableWithDelegate<OffersModel> implements ViewModel {
private final BSFormatter formatter;
@ -38,12 +39,12 @@ class OffersPM extends PresentationModel<OffersModel> {
void removeOffer(OfferListItem item) {
model.removeOffer(item);
delegate.removeOffer(item);
}
public ObservableList<OfferListItem> getList() {
return model.getList();
return delegate.getList();
}
String getTradeId(OfferListItem item) {
@ -63,7 +64,7 @@ class OffersPM extends PresentationModel<OffersModel> {
}
String getDirectionLabel(OfferListItem item) {
return (item != null) ? formatter.formatDirection(model.getDirection(item.getOffer())) : "";
return (item != null) ? formatter.formatDirection(delegate.getDirection(item.getOffer())) : "";
}
String getDate(OfferListItem item) {

View File

@ -21,7 +21,8 @@ import io.bitsquare.btc.AddressEntry;
import io.bitsquare.btc.FeePolicy;
import io.bitsquare.btc.WalletService;
import io.bitsquare.btc.listeners.TxConfidenceListener;
import io.bitsquare.gui.UIModel;
import io.bitsquare.gui.Activatable;
import io.bitsquare.gui.DataModel;
import io.bitsquare.offer.Direction;
import io.bitsquare.offer.Offer;
import io.bitsquare.trade.Trade;
@ -54,7 +55,7 @@ import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
class PendingTradesModel extends UIModel {
class PendingTradesModel implements Activatable, DataModel {
private static final Logger log = LoggerFactory.getLogger(PendingTradesModel.class);
private final TradeManager tradeManager;
@ -98,8 +99,6 @@ class PendingTradesModel extends UIModel {
@Override
public void activate() {
super.activate();
list.clear();
// transform trades to list of PendingTradesListItems and keep it updated
tradeManager.getPendingTrades().values().stream()
@ -122,8 +121,6 @@ class PendingTradesModel extends UIModel {
@Override
public void deactivate() {
super.deactivate();
tradeManager.getPendingTrades().removeListener(mapChangeListener);
cleanUpSelectedTrade();
}

View File

@ -18,7 +18,8 @@
package io.bitsquare.gui.main.portfolio.pending;
import io.bitsquare.btc.WalletService;
import io.bitsquare.gui.PresentationModel;
import io.bitsquare.gui.ActivatableWithDelegate;
import io.bitsquare.gui.ViewModel;
import io.bitsquare.gui.util.BSFormatter;
import io.bitsquare.gui.util.validation.BtcAddressValidator;
import io.bitsquare.locale.BSResources;
@ -43,7 +44,7 @@ import javafx.collections.ObservableList;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
class PendingTradesPM extends PresentationModel<PendingTradesModel> {
class PendingTradesPM extends ActivatableWithDelegate<PendingTradesModel> implements ViewModel {
private static final Logger log = LoggerFactory.getLogger(PendingTradesPM.class);
enum State {
@ -69,9 +70,9 @@ class PendingTradesPM extends PresentationModel<PendingTradesModel> {
@Inject
public PendingTradesPM(PendingTradesModel model, BSFormatter formatter,
public PendingTradesPM(PendingTradesModel delegate, BSFormatter formatter,
BtcAddressValidator btcAddressValidator) {
super(model);
super(delegate);
this.formatter = formatter;
this.btcAddressValidator = btcAddressValidator;
@ -79,42 +80,38 @@ class PendingTradesPM extends PresentationModel<PendingTradesModel> {
}
@Override
public void activate() {
super.activate();
public void doActivate() {
txId.bind(delegate.txId);
fault.bind(delegate.fault);
txId.bind(model.txId);
fault.bind(model.fault);
model.tradeState.addListener(stateChangeListener);
delegate.tradeState.addListener(stateChangeListener);
updateState();
}
@Override
public void deactivate() {
super.deactivate();
public void doDeactivate() {
txId.unbind();
fault.unbind();
model.tradeState.removeListener(stateChangeListener);
delegate.tradeState.removeListener(stateChangeListener);
}
void selectTrade(PendingTradesListItem item) {
model.selectTrade(item);
delegate.selectTrade(item);
updateState();
}
void fiatPaymentStarted() {
model.fiatPaymentStarted();
delegate.fiatPaymentStarted();
}
void fiatPaymentReceived() {
model.fiatPaymentReceived();
delegate.fiatPaymentReceived();
}
void withdraw(String withdrawToAddress) {
model.withdraw(withdrawToAddress);
delegate.withdraw(withdrawToAddress);
}
void withdrawAddressFocusOut(String text) {
@ -122,27 +119,27 @@ class PendingTradesPM extends PresentationModel<PendingTradesModel> {
}
String getAmountToWithdraw() {
return formatter.formatCoinWithCode(model.getAmountToWithdraw()); //.subtract(FeePolicy.TX_FEE));
return formatter.formatCoinWithCode(delegate.getAmountToWithdraw()); //.subtract(FeePolicy.TX_FEE));
}
ObservableList<PendingTradesListItem> getList() {
return model.getList();
return delegate.getList();
}
boolean isOfferer() {
return model.isOfferer();
return delegate.isOfferer();
}
WalletService getWalletService() {
return model.getWalletService();
return delegate.getWalletService();
}
PendingTradesListItem getSelectedItem() {
return model.getSelectedItem();
return delegate.getSelectedItem();
}
String getCurrencyCode() {
return model.getCurrencyCode();
return delegate.getCurrencyCode();
}
// columns
@ -163,7 +160,7 @@ class PendingTradesPM extends PresentationModel<PendingTradesModel> {
}
String evaluateDirection(PendingTradesListItem item) {
return (item != null) ? formatter.formatDirection(model.getDirection(item.getTrade().getOffer())) : "";
return (item != null) ? formatter.formatDirection(delegate.getDirection(item.getTrade().getOffer())) : "";
}
String formatDate(Date value) {
@ -172,45 +169,45 @@ class PendingTradesPM extends PresentationModel<PendingTradesModel> {
// payment
String getPaymentMethod() {
return BSResources.get(model.getTrade().getContract().getTakerBankAccount().getBankAccountType().toString());
return BSResources.get(delegate.getTrade().getContract().getTakerBankAccount().getBankAccountType().toString());
}
String getFiatAmount() {
return formatter.formatFiatWithCode(model.getTrade().getTradeVolume());
return formatter.formatFiatWithCode(delegate.getTrade().getTradeVolume());
}
String getHolderName() {
return model.getTrade().getContract().getTakerBankAccount().getAccountHolderName();
return delegate.getTrade().getContract().getTakerBankAccount().getAccountHolderName();
}
String getPrimaryId() {
return model.getTrade().getContract().getTakerBankAccount().getAccountPrimaryID();
return delegate.getTrade().getContract().getTakerBankAccount().getAccountPrimaryID();
}
String getSecondaryId() {
return model.getTrade().getContract().getTakerBankAccount().getAccountSecondaryID();
return delegate.getTrade().getContract().getTakerBankAccount().getAccountSecondaryID();
}
// summary
String getTradeVolume() {
return formatter.formatCoinWithCode(model.getTrade().getTradeAmount());
return formatter.formatCoinWithCode(delegate.getTrade().getTradeAmount());
}
String getFiatVolume() {
return formatter.formatFiatWithCode(model.getTrade().getTradeVolume());
return formatter.formatFiatWithCode(delegate.getTrade().getTradeVolume());
}
String getTotalFees() {
return formatter.formatCoinWithCode(model.getTotalFees());
return formatter.formatCoinWithCode(delegate.getTotalFees());
}
String getSecurityDeposit() {
// securityDeposit is handled different for offerer and taker.
// Offerer have paid in the max amount, but taker might have taken less so also paid in less securityDeposit
if (model.isOfferer())
return formatter.formatCoinWithCode(model.getTrade().getOffer().getSecurityDeposit());
if (delegate.isOfferer())
return formatter.formatCoinWithCode(delegate.getTrade().getOffer().getSecurityDeposit());
else
return formatter.formatCoinWithCode(model.getTrade().getSecurityDeposit());
return formatter.formatCoinWithCode(delegate.getTrade().getSecurityDeposit());
}
BtcAddressValidator getBtcAddressValidator() {
@ -219,25 +216,25 @@ class PendingTradesPM extends PresentationModel<PendingTradesModel> {
private void updateState() {
Trade.State tradeState = model.tradeState.get();
Trade.State tradeState = delegate.tradeState.get();
log.trace("tradeState " + tradeState);
if (tradeState != null) {
switch (tradeState) {
// TODO Check why OFFERER_ACCEPTED can happen, refactor state handling
case OFFERER_ACCEPTED:
case DEPOSIT_PUBLISHED:
state.set(model.isOfferer() ? State.OFFERER_BUYER_WAIT_TX_CONF : State.TAKER_SELLER_WAIT_TX_CONF);
state.set(delegate.isOfferer() ? State.OFFERER_BUYER_WAIT_TX_CONF : State.TAKER_SELLER_WAIT_TX_CONF);
break;
case DEPOSIT_CONFIRMED:
state.set(model.isOfferer() ? State.OFFERER_BUYER_START_PAYMENT :
state.set(delegate.isOfferer() ? State.OFFERER_BUYER_START_PAYMENT :
State.TAKER_SELLER_WAIT_PAYMENT_STARTED);
break;
case PAYMENT_STARTED:
state.set(model.isOfferer() ? State.OFFERER_BUYER_WAIT_CONFIRM_PAYMENT_RECEIVED :
state.set(delegate.isOfferer() ? State.OFFERER_BUYER_WAIT_CONFIRM_PAYMENT_RECEIVED :
State.TAKER_SELLER_CONFIRM_RECEIVE_PAYMENT);
break;
case COMPLETED:
state.set(model.isOfferer() ? State.OFFERER_BUYER_COMPLETED : State.TAKER_SELLER_COMPLETED);
state.set(delegate.isOfferer() ? State.OFFERER_BUYER_COMPLETED : State.TAKER_SELLER_COMPLETED);
break;
case FAILED:
// TODO error states not implemented yet

View File

@ -17,7 +17,8 @@
package io.bitsquare.gui.main.settings.application;
import io.bitsquare.gui.UIModel;
import io.bitsquare.gui.Activatable;
import io.bitsquare.gui.DataModel;
import io.bitsquare.settings.Preferences;
import com.google.inject.Inject;
@ -30,7 +31,7 @@ import javafx.beans.value.ChangeListener;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
class PreferencesModel extends UIModel {
class PreferencesModel implements Activatable, DataModel {
private final Preferences preferences;
@ -58,8 +59,6 @@ class PreferencesModel extends UIModel {
@Override
public void activate() {
super.activate();
useAnimations.set(preferences.getUseAnimations());
useEffects.set(preferences.getUseEffects());
btcDenomination.set(preferences.getBtcDenomination());
@ -71,8 +70,6 @@ class PreferencesModel extends UIModel {
@Override
public void deactivate() {
super.deactivate();
useAnimations.removeListener(useAnimationsListener);
useEffects.removeListener(useEffectsListener);
btcDenomination.removeListener(btcDenominationListener);

View File

@ -17,7 +17,8 @@
package io.bitsquare.gui.main.settings.application;
import io.bitsquare.gui.PresentationModel;
import io.bitsquare.gui.ActivatableWithDelegate;
import io.bitsquare.gui.ViewModel;
import com.google.inject.Inject;
@ -25,7 +26,7 @@ import javafx.beans.property.BooleanProperty;
import javafx.beans.property.StringProperty;
import javafx.collections.ObservableList;
class PreferencesPM extends PresentationModel<PreferencesModel> {
class PreferencesPM extends ActivatableWithDelegate<PreferencesModel> implements ViewModel {
@Inject
public PreferencesPM(PreferencesModel model) {
@ -33,19 +34,19 @@ class PreferencesPM extends PresentationModel<PreferencesModel> {
}
public ObservableList<String> getBtcDenominationItems() {
return model.btcDenominations;
return delegate.btcDenominations;
}
BooleanProperty useAnimations() {
return model.useAnimations;
return delegate.useAnimations;
}
BooleanProperty useEffects() {
return model.useEffects;
return delegate.useEffects;
}
StringProperty btcDenomination() {
return model.btcDenomination;
return delegate.btcDenomination;
}

View File

@ -24,7 +24,8 @@ import io.bitsquare.btc.AddressEntry;
import io.bitsquare.btc.FeePolicy;
import io.bitsquare.btc.WalletService;
import io.bitsquare.btc.listeners.BalanceListener;
import io.bitsquare.gui.UIModel;
import io.bitsquare.gui.Activatable;
import io.bitsquare.gui.DataModel;
import io.bitsquare.gui.util.BSFormatter;
import io.bitsquare.locale.Country;
import io.bitsquare.offer.Direction;
@ -64,7 +65,7 @@ import static com.google.common.base.Preconditions.checkArgument;
* Note that the create offer domain has a deeper scope in the application domain (TradeManager).
* That model is just responsible for the domain specific parts displayed needed in that UI element.
*/
class CreateOfferModel extends UIModel {
class CreateOfferModel implements Activatable, DataModel {
private static final Logger log = LoggerFactory.getLogger(CreateOfferModel.class);
private final TradeManager tradeManager;
@ -151,8 +152,6 @@ class CreateOfferModel extends UIModel {
@Override
public void activate() {
super.activate();
// might be changed after screen change
if (accountSettings != null) {
// set it here again to cover the case of an securityDeposit change after a screen change
@ -165,6 +164,11 @@ class CreateOfferModel extends UIModel {
}
}
@Override
public void deactivate() {
// no-op
}
void placeOffer() {
// data validation is done in the trade domain
tradeManager.requestPlaceOffer(offerId,

View File

@ -18,7 +18,8 @@
package io.bitsquare.gui.main.trade.createoffer;
import io.bitsquare.btc.WalletService;
import io.bitsquare.gui.PresentationModel;
import io.bitsquare.gui.ActivatableWithDelegate;
import io.bitsquare.gui.ViewModel;
import io.bitsquare.gui.util.BSFormatter;
import io.bitsquare.gui.util.validation.BtcValidator;
import io.bitsquare.gui.util.validation.FiatValidator;
@ -43,7 +44,7 @@ import javafx.beans.property.StringProperty;
import static javafx.beans.binding.Bindings.createStringBinding;
class CreateOfferPM extends PresentationModel<CreateOfferModel> {
class CreateOfferPM extends ActivatableWithDelegate<CreateOfferModel> implements ViewModel {
private final BtcValidator btcValidator;
private final BSFormatter formatter;
@ -113,39 +114,39 @@ class CreateOfferPM extends PresentationModel<CreateOfferModel> {
// setOfferBookFilter is a one time call
void initWithData(Direction direction, Coin amount, Fiat price) {
model.setDirection(direction);
directionLabel.set(model.getDirection() == Direction.BUY ? BSResources.get("shared.buy") : BSResources.get
delegate.setDirection(direction);
directionLabel.set(delegate.getDirection() == Direction.BUY ? BSResources.get("shared.buy") : BSResources.get
("shared.sell"));
// apply only if valid
boolean amountValid = false;
if (amount != null && isBtcInputValid(amount.toPlainString())
.isValid) {
model.amountAsCoin.set(amount);
model.minAmountAsCoin.set(amount);
delegate.amountAsCoin.set(amount);
delegate.minAmountAsCoin.set(amount);
amountValid = true;
}
// apply only if valid
boolean priceValid = false;
if (price != null && isBtcInputValid(price.toPlainString()).isValid) {
model.priceAsFiat.set(formatter.parseToFiatWith2Decimals(price.toPlainString()));
delegate.priceAsFiat.set(formatter.parseToFiatWith2Decimals(price.toPlainString()));
priceValid = true;
}
if (amountValid && priceValid)
model.calculateTotalToPay();
delegate.calculateTotalToPay();
}
void placeOffer() {
model.requestPlaceOfferErrorMessage.set(null);
model.requestPlaceOfferSuccess.set(false);
delegate.requestPlaceOfferErrorMessage.set(null);
delegate.requestPlaceOfferSuccess.set(false);
isPlaceOfferButtonDisabled.set(true);
isPlaceOfferSpinnerVisible.set(true);
model.placeOffer();
delegate.placeOffer();
}
@ -163,12 +164,12 @@ class CreateOfferPM extends PresentationModel<CreateOfferModel> {
// only allow max 4 decimal places for btc values
setAmountToModel();
// reformat input
amount.set(formatter.formatCoin(model.amountAsCoin.get()));
amount.set(formatter.formatCoin(delegate.amountAsCoin.get()));
calculateVolume();
// handle minAmount/amount relationship
if (!model.isMinAmountLessOrEqualAmount()) {
if (!delegate.isMinAmountLessOrEqualAmount()) {
amountValidationResult.set(new InputValidator.ValidationResult(false,
BSResources.get("createOffer.validation.amountSmallerThanMinAmount")));
}
@ -188,9 +189,9 @@ class CreateOfferPM extends PresentationModel<CreateOfferModel> {
if (result.isValid) {
showWarningInvalidBtcDecimalPlaces.set(!formatter.hasBtcValidDecimals(userInput));
setMinAmountToModel();
minAmount.set(formatter.formatCoin(model.minAmountAsCoin.get()));
minAmount.set(formatter.formatCoin(delegate.minAmountAsCoin.get()));
if (!model.isMinAmountLessOrEqualAmount()) {
if (!delegate.isMinAmountLessOrEqualAmount()) {
minAmountValidationResult.set(new InputValidator.ValidationResult(false,
BSResources.get("createOffer.validation.minAmountLargerThanAmount")));
}
@ -211,7 +212,7 @@ class CreateOfferPM extends PresentationModel<CreateOfferModel> {
if (isValid) {
showWarningInvalidFiatDecimalPlaces.set(!formatter.hasFiatValidDecimals(userInput));
setPriceToModel();
price.set(formatter.formatFiat(model.priceAsFiat.get()));
price.set(formatter.formatFiat(delegate.priceAsFiat.get()));
calculateVolume();
}
@ -225,7 +226,7 @@ class CreateOfferPM extends PresentationModel<CreateOfferModel> {
if (result.isValid) {
showWarningInvalidFiatDecimalPlaces.set(!formatter.hasFiatValidDecimals(userInput));
setVolumeToModel();
volume.set(formatter.formatFiat(model.volumeAsFiat.get()));
volume.set(formatter.formatFiat(delegate.volumeAsFiat.get()));
calculateAmount();
@ -239,12 +240,12 @@ class CreateOfferPM extends PresentationModel<CreateOfferModel> {
}
void securityDepositInfoDisplayed() {
model.securityDepositInfoDisplayed();
delegate.securityDepositInfoDisplayed();
}
WalletService getWalletService() {
return model.getWalletService();
return delegate.getWalletService();
}
BSFormatter getFormatter() {
@ -252,7 +253,7 @@ class CreateOfferPM extends PresentationModel<CreateOfferModel> {
}
Boolean displaySecurityDepositInfo() {
return model.displaySecurityDepositInfo();
return delegate.displaySecurityDepositInfo();
}
private void setupListeners() {
@ -262,7 +263,7 @@ class CreateOfferPM extends PresentationModel<CreateOfferModel> {
if (isBtcInputValid(newValue).isValid) {
setAmountToModel();
calculateVolume();
model.calculateTotalToPay();
delegate.calculateTotalToPay();
}
updateButtonDisableState();
});
@ -276,7 +277,7 @@ class CreateOfferPM extends PresentationModel<CreateOfferModel> {
if (isFiatInputValid(newValue).isValid) {
setPriceToModel();
calculateVolume();
model.calculateTotalToPay();
delegate.calculateTotalToPay();
}
updateButtonDisableState();
});
@ -285,12 +286,12 @@ class CreateOfferPM extends PresentationModel<CreateOfferModel> {
if (isFiatInputValid(newValue).isValid) {
setVolumeToModel();
setPriceToModel();
model.calculateAmount();
model.calculateTotalToPay();
delegate.calculateAmount();
delegate.calculateTotalToPay();
}
updateButtonDisableState();
});
model.isWalletFunded.addListener((ov, oldValue, newValue) -> {
delegate.isWalletFunded.addListener((ov, oldValue, newValue) -> {
if (newValue) {
updateButtonDisableState();
tabIsClosable.set(false);
@ -298,70 +299,70 @@ class CreateOfferPM extends PresentationModel<CreateOfferModel> {
});
// Binding with Bindings.createObjectBinding does not work because of bi-directional binding
model.amountAsCoin.addListener((ov, oldValue, newValue) -> amount.set(formatter.formatCoin(newValue)));
model.minAmountAsCoin.addListener((ov, oldValue, newValue) -> minAmount.set(formatter.formatCoin(newValue)));
model.priceAsFiat.addListener((ov, oldValue, newValue) -> price.set(formatter.formatFiat(newValue)));
model.volumeAsFiat.addListener((ov, oldValue, newValue) -> volume.set(formatter.formatFiat(newValue)));
delegate.amountAsCoin.addListener((ov, oldValue, newValue) -> amount.set(formatter.formatCoin(newValue)));
delegate.minAmountAsCoin.addListener((ov, oldValue, newValue) -> minAmount.set(formatter.formatCoin(newValue)));
delegate.priceAsFiat.addListener((ov, oldValue, newValue) -> price.set(formatter.formatFiat(newValue)));
delegate.volumeAsFiat.addListener((ov, oldValue, newValue) -> volume.set(formatter.formatFiat(newValue)));
model.requestPlaceOfferErrorMessage.addListener((ov, oldValue, newValue) -> {
delegate.requestPlaceOfferErrorMessage.addListener((ov, oldValue, newValue) -> {
if (newValue != null) {
isPlaceOfferButtonDisabled.set(false);
isPlaceOfferSpinnerVisible.set(false);
}
});
model.requestPlaceOfferSuccess.addListener((ov, oldValue, newValue) -> {
delegate.requestPlaceOfferSuccess.addListener((ov, oldValue, newValue) -> {
isPlaceOfferButtonVisible.set(!newValue);
isPlaceOfferSpinnerVisible.set(false);
});
// ObservableLists
model.acceptedCountries.addListener((Observable o) -> acceptedCountries.set(formatter
.countryLocalesToString(model.acceptedCountries)));
model.acceptedLanguages.addListener((Observable o) -> acceptedLanguages.set(formatter
.languageLocalesToString(model.acceptedLanguages)));
model.acceptedArbitrators.addListener((Observable o) -> acceptedArbitrators.set(formatter
.arbitratorsToString(model.acceptedArbitrators)));
delegate.acceptedCountries.addListener((Observable o) -> acceptedCountries.set(formatter
.countryLocalesToString(delegate.acceptedCountries)));
delegate.acceptedLanguages.addListener((Observable o) -> acceptedLanguages.set(formatter
.languageLocalesToString(delegate.acceptedLanguages)));
delegate.acceptedArbitrators.addListener((Observable o) -> acceptedArbitrators.set(formatter
.arbitratorsToString(delegate.acceptedArbitrators)));
}
private void setupBindings() {
totalToPay.bind(createStringBinding(() -> formatter.formatCoinWithCode(model.totalToPayAsCoin.get()),
model.totalToPayAsCoin));
securityDeposit.bind(createStringBinding(() -> formatter.formatCoinWithCode(model.securityDepositAsCoin.get()),
model.securityDepositAsCoin));
totalToPay.bind(createStringBinding(() -> formatter.formatCoinWithCode(delegate.totalToPayAsCoin.get()),
delegate.totalToPayAsCoin));
securityDeposit.bind(createStringBinding(() -> formatter.formatCoinWithCode(delegate.securityDepositAsCoin.get()),
delegate.securityDepositAsCoin));
totalToPayAsCoin.bind(model.totalToPayAsCoin);
totalToPayAsCoin.bind(delegate.totalToPayAsCoin);
offerFee.bind(createStringBinding(() -> formatter.formatCoinWithCode(model.offerFeeAsCoin.get()),
model.offerFeeAsCoin));
networkFee.bind(createStringBinding(() -> formatter.formatCoinWithCode(model.networkFeeAsCoin.get()),
model.offerFeeAsCoin));
offerFee.bind(createStringBinding(() -> formatter.formatCoinWithCode(delegate.offerFeeAsCoin.get()),
delegate.offerFeeAsCoin));
networkFee.bind(createStringBinding(() -> formatter.formatCoinWithCode(delegate.networkFeeAsCoin.get()),
delegate.offerFeeAsCoin));
bankAccountType.bind(Bindings.createStringBinding(() -> BSResources.get(model.bankAccountType.get()),
model.bankAccountType));
bankAccountCurrency.bind(model.bankAccountCurrency);
bankAccountCounty.bind(model.bankAccountCounty);
bankAccountType.bind(Bindings.createStringBinding(() -> BSResources.get(delegate.bankAccountType.get()),
delegate.bankAccountType));
bankAccountCurrency.bind(delegate.bankAccountCurrency);
bankAccountCounty.bind(delegate.bankAccountCounty);
requestPlaceOfferErrorMessage.bind(model.requestPlaceOfferErrorMessage);
showTransactionPublishedScreen.bind(model.requestPlaceOfferSuccess);
transactionId.bind(model.transactionId);
requestPlaceOfferErrorMessage.bind(delegate.requestPlaceOfferErrorMessage);
showTransactionPublishedScreen.bind(delegate.requestPlaceOfferSuccess);
transactionId.bind(delegate.transactionId);
btcCode.bind(model.btcCode);
fiatCode.bind(model.fiatCode);
btcCode.bind(delegate.btcCode);
fiatCode.bind(delegate.fiatCode);
}
private void calculateVolume() {
setAmountToModel();
setPriceToModel();
model.calculateVolume();
delegate.calculateVolume();
}
private void calculateAmount() {
setVolumeToModel();
setPriceToModel();
model.calculateAmount();
delegate.calculateAmount();
// Amount calculation could lead to amount/minAmount invalidation
if (!model.isMinAmountLessOrEqualAmount()) {
if (!delegate.isMinAmountLessOrEqualAmount()) {
amountValidationResult.set(new InputValidator.ValidationResult(false,
BSResources.get("createOffer.validation.amountSmallerThanMinAmount")));
}
@ -374,19 +375,19 @@ class CreateOfferPM extends PresentationModel<CreateOfferModel> {
}
private void setAmountToModel() {
model.amountAsCoin.set(formatter.parseToCoinWith4Decimals(amount.get()));
delegate.amountAsCoin.set(formatter.parseToCoinWith4Decimals(amount.get()));
}
private void setMinAmountToModel() {
model.minAmountAsCoin.set(formatter.parseToCoinWith4Decimals(minAmount.get()));
delegate.minAmountAsCoin.set(formatter.parseToCoinWith4Decimals(minAmount.get()));
}
private void setPriceToModel() {
model.priceAsFiat.set(formatter.parseToFiatWith2Decimals(price.get()));
delegate.priceAsFiat.set(formatter.parseToFiatWith2Decimals(price.get()));
}
private void setVolumeToModel() {
model.volumeAsFiat.set(formatter.parseToFiatWith2Decimals(volume.get()));
delegate.volumeAsFiat.set(formatter.parseToFiatWith2Decimals(volume.get()));
}
private void updateButtonDisableState() {
@ -394,8 +395,8 @@ class CreateOfferPM extends PresentationModel<CreateOfferModel> {
isBtcInputValid(minAmount.get()).isValid &&
isBtcInputValid(price.get()).isValid &&
isBtcInputValid(volume.get()).isValid &&
model.isMinAmountLessOrEqualAmount() &&
model.isWalletFunded.get())
delegate.isMinAmountLessOrEqualAmount() &&
delegate.isWalletFunded.get())
);
}

View File

@ -18,7 +18,8 @@
package io.bitsquare.gui.main.trade.offerbook;
import io.bitsquare.bank.BankAccount;
import io.bitsquare.gui.UIModel;
import io.bitsquare.gui.Activatable;
import io.bitsquare.gui.DataModel;
import io.bitsquare.gui.util.BSFormatter;
import io.bitsquare.locale.Country;
import io.bitsquare.locale.CurrencyUtil;
@ -51,7 +52,7 @@ import org.slf4j.LoggerFactory;
/**
* It holds the scope specific domain data for either a buy or sell UI screen.
*/
class OfferBookModel extends UIModel {
class OfferBookModel implements Activatable, DataModel {
private static final Logger log = LoggerFactory.getLogger(OfferBookModel.class);
private final User user;
@ -93,8 +94,6 @@ class OfferBookModel extends UIModel {
@Override
public void activate() {
super.activate();
amountAsCoin.set(null);
priceAsFiat.set(null);
volumeAsFiat.set(null);
@ -109,8 +108,6 @@ class OfferBookModel extends UIModel {
@Override
public void deactivate() {
super.deactivate();
offerBook.removeClient();
user.currentBankAccountProperty().removeListener(bankAccountChangeListener);
btcCode.unbind();

View File

@ -17,7 +17,8 @@
package io.bitsquare.gui.main.trade.offerbook;
import io.bitsquare.gui.PresentationModel;
import io.bitsquare.gui.ActivatableWithDelegate;
import io.bitsquare.gui.ViewModel;
import io.bitsquare.gui.util.BSFormatter;
import io.bitsquare.gui.util.validation.InputValidator;
import io.bitsquare.gui.util.validation.OptionalBtcValidator;
@ -35,7 +36,7 @@ import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.collections.transformation.SortedList;
class OfferBookPM extends PresentationModel<OfferBookModel> {
class OfferBookPM extends ActivatableWithDelegate<OfferBookModel> implements ViewModel {
private final OptionalBtcValidator optionalBtcValidator;
private final BSFormatter formatter;
@ -50,17 +51,17 @@ class OfferBookPM extends PresentationModel<OfferBookModel> {
@Inject
public OfferBookPM(OfferBookModel model, OptionalFiatValidator optionalFiatValidator,
public OfferBookPM(OfferBookModel delegate, OptionalFiatValidator optionalFiatValidator,
OptionalBtcValidator optionalBtcValidator, BSFormatter formatter) {
super(model);
super(delegate);
this.optionalFiatValidator = optionalFiatValidator;
this.optionalBtcValidator = optionalBtcValidator;
this.formatter = formatter;
btcCode.bind(model.btcCode);
fiatCode.bind(model.fiatCode);
restrictionsInfo.bind(model.restrictionsInfo);
btcCode.bind(delegate.btcCode);
fiatCode.bind(delegate.fiatCode);
restrictionsInfo.bind(delegate.restrictionsInfo);
// Bidirectional bindings are used for all input fields: amount, price and volume
// We do volume/amount calculation during input, so user has immediate feedback
@ -68,7 +69,7 @@ class OfferBookPM extends PresentationModel<OfferBookModel> {
if (isBtcInputValid(newValue).isValid) {
setAmountToModel();
setPriceToModel();
model.calculateVolume();
delegate.calculateVolume();
}
});
@ -76,7 +77,7 @@ class OfferBookPM extends PresentationModel<OfferBookModel> {
if (isFiatInputValid(newValue).isValid) {
setAmountToModel();
setPriceToModel();
model.calculateVolume();
delegate.calculateVolume();
}
});
@ -84,42 +85,42 @@ class OfferBookPM extends PresentationModel<OfferBookModel> {
if (isFiatInputValid(newValue).isValid) {
setPriceToModel();
setVolumeToModel();
model.calculateAmount();
delegate.calculateAmount();
}
});
// Binding with Bindings.createObjectBinding does not work because of bi-directional binding
model.amountAsCoinProperty().addListener((ov, oldValue, newValue) -> amount.set(formatter.formatCoin
delegate.amountAsCoinProperty().addListener((ov, oldValue, newValue) -> amount.set(formatter.formatCoin
(newValue)));
model.priceAsFiatProperty().addListener((ov, oldValue, newValue) -> price.set(formatter.formatFiat(newValue)));
model.volumeAsFiatProperty().addListener((ov, oldValue, newValue) -> volume.set(formatter.formatFiat
delegate.priceAsFiatProperty().addListener((ov, oldValue, newValue) -> price.set(formatter.formatFiat(newValue)));
delegate.volumeAsFiatProperty().addListener((ov, oldValue, newValue) -> volume.set(formatter.formatFiat
(newValue)));
}
void removeOffer(Offer offer) {
model.removeOffer(offer);
delegate.removeOffer(offer);
}
boolean isTradable(Offer offer) {
return model.isTradable(offer);
return delegate.isTradable(offer);
}
void setDirection(Direction direction) {
model.setDirection(direction);
delegate.setDirection(direction);
}
SortedList<OfferBookListItem> getOfferList() {
return model.getOfferList();
return delegate.getOfferList();
}
boolean isRegistered() {
return model.isRegistered();
return delegate.isRegistered();
}
boolean isMyOffer(Offer offer) {
return model.isMyOffer(offer);
return delegate.isMyOffer(offer);
}
String getAmount(OfferBookListItem item) {
@ -145,15 +146,15 @@ class OfferBookPM extends PresentationModel<OfferBookModel> {
}
Direction getDirection() {
return model.getDirection();
return delegate.getDirection();
}
Coin getAmountAsCoin() {
return model.getAmountAsCoin();
return delegate.getAmountAsCoin();
}
Fiat getPriceAsCoin() {
return model.getPriceAsFiat();
return delegate.getPriceAsFiat();
}
private InputValidator.ValidationResult isBtcInputValid(String input) {
@ -165,15 +166,15 @@ class OfferBookPM extends PresentationModel<OfferBookModel> {
}
private void setAmountToModel() {
model.setAmount(formatter.parseToCoinWith4Decimals(amount.get()));
delegate.setAmount(formatter.parseToCoinWith4Decimals(amount.get()));
}
private void setPriceToModel() {
model.setPrice(formatter.parseToFiatWith2Decimals(price.get()));
delegate.setPrice(formatter.parseToFiatWith2Decimals(price.get()));
}
private void setVolumeToModel() {
model.setVolume(formatter.parseToFiatWith2Decimals(volume.get()));
delegate.setVolume(formatter.parseToFiatWith2Decimals(volume.get()));
}
}

View File

@ -21,7 +21,8 @@ import io.bitsquare.btc.AddressEntry;
import io.bitsquare.btc.FeePolicy;
import io.bitsquare.btc.WalletService;
import io.bitsquare.btc.listeners.BalanceListener;
import io.bitsquare.gui.UIModel;
import io.bitsquare.gui.Activatable;
import io.bitsquare.gui.DataModel;
import io.bitsquare.offer.Offer;
import io.bitsquare.persistence.Persistence;
import io.bitsquare.settings.Preferences;
@ -51,7 +52,7 @@ import org.slf4j.LoggerFactory;
* Note that the create offer domain has a deeper scope in the application domain (TradeManager).
* That model is just responsible for the domain specific parts displayed needed in that UI element.
*/
class TakeOfferModel extends UIModel {
class TakeOfferModel implements Activatable, DataModel {
private static final Logger log = LoggerFactory.getLogger(TakeOfferModel.class);
private final TradeManager tradeManager;
@ -92,16 +93,11 @@ class TakeOfferModel extends UIModel {
@Override
public void activate() {
super.activate();
btcCode.bind(preferences.btcDenominationProperty());
}
@SuppressWarnings("EmptyMethod")
@Override
public void deactivate() {
super.deactivate();
btcCode.unbind();
}

View File

@ -18,7 +18,8 @@
package io.bitsquare.gui.main.trade.takeoffer;
import io.bitsquare.btc.WalletService;
import io.bitsquare.gui.PresentationModel;
import io.bitsquare.gui.ActivatableWithDelegate;
import io.bitsquare.gui.ViewModel;
import io.bitsquare.gui.util.BSFormatter;
import io.bitsquare.gui.util.validation.BtcValidator;
import io.bitsquare.gui.util.validation.InputValidator;
@ -40,7 +41,7 @@ import javafx.beans.property.StringProperty;
import static javafx.beans.binding.Bindings.createStringBinding;
class TakeOfferPM extends PresentationModel<TakeOfferModel> {
class TakeOfferPM extends ActivatableWithDelegate<TakeOfferModel> implements ViewModel {
private String fiatCode;
private String amountRange;
@ -101,13 +102,13 @@ class TakeOfferPM extends PresentationModel<TakeOfferModel> {
// setOfferBookFilter is a one time call
void initWithData(Direction direction, Coin amount, Offer offer) {
model.initWithData(amount, offer);
delegate.initWithData(amount, offer);
directionLabel = direction == Direction.BUY ?
BSResources.get("shared.buy") : BSResources.get("shared.sell");
fiatCode = offer.getCurrency().getCurrencyCode();
if (!model.isMinAmountLessOrEqualAmount()) {
if (!delegate.isMinAmountLessOrEqualAmount()) {
amountValidationResult.set(new InputValidator.ValidationResult(false,
BSResources.get("takeOffer.validation.amountSmallerThanMinAmount")));
}
@ -121,9 +122,9 @@ class TakeOfferPM extends PresentationModel<TakeOfferModel> {
price = formatter.formatFiatWithCode(offer.getPrice());
paymentLabel = BSResources.get("takeOffer.fundsBox.paymentLabel", offer.getId());
if (model.getAddressEntry() != null) {
addressAsString = model.getAddressEntry().getAddress().toString();
address.set(model.getAddressEntry().getAddress());
if (delegate.getAddressEntry() != null) {
addressAsString = delegate.getAddressEntry().getAddress().toString();
address.set(delegate.getAddressEntry().getAddress());
}
acceptedCountries = formatter.countryLocalesToString(offer.getAcceptedCountries());
@ -136,17 +137,17 @@ class TakeOfferPM extends PresentationModel<TakeOfferModel> {
void takeOffer() {
model.requestTakeOfferErrorMessage.set(null);
model.requestTakeOfferSuccess.set(false);
delegate.requestTakeOfferErrorMessage.set(null);
delegate.requestTakeOfferSuccess.set(false);
isTakeOfferButtonDisabled.set(true);
isTakeOfferSpinnerVisible.set(true);
model.takeOffer();
delegate.takeOffer();
}
void securityDepositInfoDisplayed() {
model.securityDepositInfoDisplayed();
delegate.securityDepositInfoDisplayed();
}
@ -164,15 +165,15 @@ class TakeOfferPM extends PresentationModel<TakeOfferModel> {
// only allow max 4 decimal places for btc values
setAmountToModel();
// reformat input
amount.set(formatter.formatCoin(model.amountAsCoin.get()));
amount.set(formatter.formatCoin(delegate.amountAsCoin.get()));
calculateVolume();
if (!model.isMinAmountLessOrEqualAmount())
if (!delegate.isMinAmountLessOrEqualAmount())
amountValidationResult.set(new InputValidator.ValidationResult(false,
BSResources.get("takeOffer.validation.amountSmallerThanMinAmount")));
if (model.isAmountLargerThanOfferAmount())
if (delegate.isAmountLargerThanOfferAmount())
amountValidationResult.set(new InputValidator.ValidationResult(false,
BSResources.get("takeOffer.validation.amountLargerThanOfferAmount")));
}
@ -181,7 +182,7 @@ class TakeOfferPM extends PresentationModel<TakeOfferModel> {
WalletService getWalletService() {
return model.getWalletService();
return delegate.getWalletService();
}
BSFormatter getFormatter() {
@ -201,7 +202,7 @@ class TakeOfferPM extends PresentationModel<TakeOfferModel> {
}
String getAmount() {
return formatter.formatCoinWithCode(model.amountAsCoin.get());
return formatter.formatCoinWithCode(delegate.amountAsCoin.get());
}
String getAmountRange() {
@ -249,7 +250,7 @@ class TakeOfferPM extends PresentationModel<TakeOfferModel> {
}
Boolean displaySecurityDepositInfo() {
return model.displaySecurityDepositInfo();
return delegate.displaySecurityDepositInfo();
}
@ -260,12 +261,12 @@ class TakeOfferPM extends PresentationModel<TakeOfferModel> {
if (isBtcInputValid(newValue).isValid) {
setAmountToModel();
calculateVolume();
model.calculateTotalToPay();
delegate.calculateTotalToPay();
}
updateButtonDisableState();
});
model.isWalletFunded.addListener((ov, oldValue, newValue) -> {
delegate.isWalletFunded.addListener((ov, oldValue, newValue) -> {
if (newValue) {
updateButtonDisableState();
tabIsClosable.set(false);
@ -273,51 +274,51 @@ class TakeOfferPM extends PresentationModel<TakeOfferModel> {
});
// Binding with Bindings.createObjectBinding does not work because of bi-directional binding
model.amountAsCoin.addListener((ov, oldValue, newValue) -> amount.set(formatter.formatCoin(newValue)));
delegate.amountAsCoin.addListener((ov, oldValue, newValue) -> amount.set(formatter.formatCoin(newValue)));
model.requestTakeOfferErrorMessage.addListener((ov, oldValue, newValue) -> {
delegate.requestTakeOfferErrorMessage.addListener((ov, oldValue, newValue) -> {
if (newValue != null) {
isTakeOfferButtonDisabled.set(false);
isTakeOfferSpinnerVisible.set(false);
}
});
model.requestTakeOfferSuccess.addListener((ov, oldValue, newValue) -> {
delegate.requestTakeOfferSuccess.addListener((ov, oldValue, newValue) -> {
isTakeOfferButtonVisible.set(!newValue);
isTakeOfferSpinnerVisible.set(false);
});
}
private void setupBindings() {
volume.bind(createStringBinding(() -> formatter.formatFiatWithCode(model.volumeAsFiat.get()),
model.volumeAsFiat));
totalToPay.bind(createStringBinding(() -> formatter.formatCoinWithCode(model.totalToPayAsCoin.get()),
model.totalToPayAsCoin));
securityDeposit.bind(createStringBinding(() -> formatter.formatCoinWithCode(model.securityDepositAsCoin.get()),
model.securityDepositAsCoin));
volume.bind(createStringBinding(() -> formatter.formatFiatWithCode(delegate.volumeAsFiat.get()),
delegate.volumeAsFiat));
totalToPay.bind(createStringBinding(() -> formatter.formatCoinWithCode(delegate.totalToPayAsCoin.get()),
delegate.totalToPayAsCoin));
securityDeposit.bind(createStringBinding(() -> formatter.formatCoinWithCode(delegate.securityDepositAsCoin.get()),
delegate.securityDepositAsCoin));
totalToPayAsCoin.bind(model.totalToPayAsCoin);
totalToPayAsCoin.bind(delegate.totalToPayAsCoin);
requestTakeOfferErrorMessage.bind(model.requestTakeOfferErrorMessage);
showTransactionPublishedScreen.bind(model.requestTakeOfferSuccess);
transactionId.bind(model.transactionId);
requestTakeOfferErrorMessage.bind(delegate.requestTakeOfferErrorMessage);
showTransactionPublishedScreen.bind(delegate.requestTakeOfferSuccess);
transactionId.bind(delegate.transactionId);
btcCode.bind(model.btcCode);
btcCode.bind(delegate.btcCode);
}
private void calculateVolume() {
setAmountToModel();
model.calculateVolume();
delegate.calculateVolume();
}
private void setAmountToModel() {
model.amountAsCoin.set(formatter.parseToCoinWith4Decimals(amount.get()));
delegate.amountAsCoin.set(formatter.parseToCoinWith4Decimals(amount.get()));
}
private void updateButtonDisableState() {
isTakeOfferButtonDisabled.set(!(isBtcInputValid(amount.get()).isValid &&
model.isMinAmountLessOrEqualAmount() &&
!model.isAmountLargerThanOfferAmount() &&
model.isWalletFunded.get())
delegate.isMinAmountLessOrEqualAmount() &&
!delegate.isAmountLargerThanOfferAmount() &&
delegate.isWalletFunded.get())
);
}

View File

@ -38,8 +38,8 @@
<logger name="io.netty.channel" level="WARN"/>
<logger name="io.netty.buffer" level="WARN"/>
<logger name="io.bitsquare.gui.UIModel" level="WARN"/>
<logger name="io.bitsquare.gui.PresentationModel" level="WARN"/>
<logger name="io.bitsquare.gui.DataModel" level="WARN"/>
<logger name="io.bitsquare.gui.ActivatableWithDelegate" level="WARN"/>
<logger name="io.bitsquare.gui.ViewController" level="WARN"/>
<logger name="io.bitsquare.gui.ViewCB" level="WARN"/>
<logger name="io.bitsquare.gui.CachedViewCB" level="WARN"/>