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/>. * 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; public interface Activatable {
void activate();
import com.google.inject.Inject;
class ChangePasswordModel extends UIModel {
@Inject
public ChangePasswordModel() {
}
@SuppressWarnings("EmptyMethod")
void savePassword(String password) {
//TODO Implement password encryption for wallet
}
void deactivate();
} }

View file

@ -15,27 +15,33 @@
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>. * 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; public abstract class ActivatableWithDelegate<D extends Activatable> extends WithDelegate<D> implements Activatable {
import io.bitsquare.gui.UIModel;
import com.google.inject.Inject; public ActivatableWithDelegate(D delegate) {
super(delegate);
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();
} }
List<String> getMnemonicCode() { @Override
return mnemonicCode; 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. * active and awake it at reactivation.
* * @param <T> The PresentationModel used in that class * * @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); private static final Logger log = LoggerFactory.getLogger(CachedViewCB.class);
protected final T presentationModel; protected final T presentationModel;

View file

@ -17,17 +17,5 @@
package io.bitsquare.gui; package io.bitsquare.gui;
import org.slf4j.Logger; public interface DataModel {
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());
}
} }

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/>. * along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
*/ */
package io.bitsquare.gui.main.account; package io.bitsquare.gui;
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;
}
public interface ViewModel {
} }

View file

@ -15,23 +15,13 @@
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>. * 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 { protected WithDelegate(D delegate) {
this.delegate = delegate;
@Inject
public PasswordModel() {
} }
@SuppressWarnings("EmptyMethod")
void savePassword(String password) {
//TODO Implement password encryption for wallet
}
} }

View file

@ -17,19 +17,21 @@
package io.bitsquare.gui.main.account; 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; import com.google.inject.Inject;
class AccountPM extends PresentationModel<AccountModel> { class AccountPM implements ViewModel {
private final User user;
@Inject @Inject
public AccountPM(AccountModel model) { public AccountPM(User user) {
super(model); this.user = user;
} }
boolean getNeedRegistration() { 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.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
public class AccountViewCB extends CachedViewCB<AccountPM> { public class AccountViewCB extends CachedViewCB {
private static final Logger log = LoggerFactory.getLogger(AccountViewCB.class); private static final Logger log = LoggerFactory.getLogger(AccountViewCB.class);
@ -45,6 +45,7 @@ public class AccountViewCB extends CachedViewCB<AccountPM> {
@FXML Tab accountSettingsTab, arbitratorSettingsTab; @FXML Tab accountSettingsTab, arbitratorSettingsTab;
private final AccountPM model;
private final ViewLoader viewLoader; private final ViewLoader viewLoader;
private final Navigation navigation; private final Navigation navigation;
@ -54,8 +55,9 @@ public class AccountViewCB extends CachedViewCB<AccountPM> {
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
@Inject @Inject
private AccountViewCB(AccountPM presentationModel, ViewLoader viewLoader, Navigation navigation) { private AccountViewCB(AccountPM model, ViewLoader viewLoader, Navigation navigation) {
super(presentationModel); super();
this.model = model;
this.viewLoader = viewLoader; this.viewLoader = viewLoader;
this.navigation = navigation; this.navigation = navigation;
} }
@ -96,7 +98,7 @@ public class AccountViewCB extends CachedViewCB<AccountPM> {
if (navigation.getCurrentItems().length == 2 && if (navigation.getCurrentItems().length == 2 &&
navigation.getCurrentItems()[1] == Navigation.Item.ACCOUNT) { navigation.getCurrentItems()[1] == Navigation.Item.ACCOUNT) {
if (presentationModel.getNeedRegistration()) { if (model.getNeedRegistration()) {
navigation.navigationTo(Navigation.Item.MAIN, Navigation.Item.ACCOUNT, navigation.navigationTo(Navigation.Item.MAIN, Navigation.Item.ACCOUNT,
Navigation.Item.ACCOUNT_SETUP); Navigation.Item.ACCOUNT_SETUP);
} }

View file

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

View file

@ -17,7 +17,7 @@
package io.bitsquare.gui.main.account.content.changepassword; 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.MultiStepNavigation;
import io.bitsquare.gui.main.account.content.ContextAware; import io.bitsquare.gui.main.account.content.ContextAware;
import io.bitsquare.gui.main.help.Help; import io.bitsquare.gui.main.help.Help;
@ -36,10 +36,12 @@ import javafx.scene.layout.*;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; 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 static final Logger log = LoggerFactory.getLogger(ChangePasswordViewCB.class);
private final ChangePasswordPM model;
@FXML HBox buttonsHBox; @FXML HBox buttonsHBox;
@FXML Button saveButton, skipButton; @FXML Button saveButton, skipButton;
@FXML PasswordField oldPasswordField, passwordField, repeatedPasswordField; @FXML PasswordField oldPasswordField, passwordField, repeatedPasswordField;
@ -50,8 +52,8 @@ public class ChangePasswordViewCB extends CachedViewCB<ChangePasswordPM> impleme
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
@Inject @Inject
private ChangePasswordViewCB(ChangePasswordPM presentationModel) { private ChangePasswordViewCB(ChangePasswordPM model) {
super(presentationModel); this.model = model;
} }
@ -63,31 +65,12 @@ public class ChangePasswordViewCB extends CachedViewCB<ChangePasswordPM> impleme
public void initialize(URL url, ResourceBundle rb) { public void initialize(URL url, ResourceBundle rb) {
super.initialize(url, rb); super.initialize(url, rb);
passwordField.textProperty().bindBidirectional(presentationModel.passwordField); passwordField.textProperty().bindBidirectional(model.passwordField);
repeatedPasswordField.textProperty().bindBidirectional(presentationModel.repeatedPasswordField); 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 // ContextAware implementation
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
@ -105,13 +88,13 @@ public class ChangePasswordViewCB extends CachedViewCB<ChangePasswordPM> impleme
@FXML @FXML
private void onSaved() { private void onSaved() {
boolean result = presentationModel.requestSavePassword(); boolean result = model.requestSavePassword();
if (result) { if (result) {
if (parent instanceof MultiStepNavigation) if (parent instanceof MultiStepNavigation)
((MultiStepNavigation) parent).nextStep(this); ((MultiStepNavigation) parent).nextStep(this);
} }
else { 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.account.AccountSettings;
import io.bitsquare.bank.BankAccount; import io.bitsquare.bank.BankAccount;
import io.bitsquare.bank.BankAccountType; 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.Country;
import io.bitsquare.locale.CountryUtil; import io.bitsquare.locale.CountryUtil;
import io.bitsquare.locale.CurrencyUtil; import io.bitsquare.locale.CurrencyUtil;
@ -41,7 +42,7 @@ import javafx.beans.property.StringProperty;
import javafx.collections.FXCollections; import javafx.collections.FXCollections;
import javafx.collections.ObservableList; import javafx.collections.ObservableList;
class FiatAccountModel extends UIModel { class FiatAccountModel implements Activatable, DataModel {
private final User user; private final User user;
private final AccountSettings accountSettings; private final AccountSettings accountSettings;
@ -76,11 +77,14 @@ class FiatAccountModel extends UIModel {
@Override @Override
public void activate() { public void activate() {
super.activate();
allBankAccounts.setAll(user.getBankAccounts()); allBankAccounts.setAll(user.getBankAccounts());
} }
@Override
public void deactivate() {
// no-op
}
void saveBankAccount() { void saveBankAccount() {
BankAccount bankAccount = new BankAccount(type.get(), 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.BankAccount;
import io.bitsquare.bank.BankAccountType; 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.BankAccountNumberValidator;
import io.bitsquare.gui.util.validation.InputValidator; import io.bitsquare.gui.util.validation.InputValidator;
import io.bitsquare.locale.BSResources; import io.bitsquare.locale.BSResources;
@ -40,7 +41,7 @@ import javafx.collections.ListChangeListener;
import javafx.collections.ObservableList; import javafx.collections.ObservableList;
import javafx.util.StringConverter; import javafx.util.StringConverter;
class FiatAccountPM extends PresentationModel<FiatAccountModel> { class FiatAccountPM extends ActivatableWithDelegate<FiatAccountModel> implements ViewModel {
private final BankAccountNumberValidator bankAccountNumberValidator; private final BankAccountNumberValidator bankAccountNumberValidator;
@ -85,10 +86,8 @@ class FiatAccountPM extends PresentationModel<FiatAccountModel> {
} }
@Override @Override
public void activate() { public void doActivate() {
super.activate(); delegate.allBankAccounts.addListener((ListChangeListener<BankAccount>) change -> applyAllBankAccounts());
model.allBankAccounts.addListener((ListChangeListener<BankAccount>) change -> applyAllBankAccounts());
applyAllBankAccounts(); applyAllBankAccounts();
} }
@ -96,21 +95,21 @@ class FiatAccountPM extends PresentationModel<FiatAccountModel> {
InputValidator.ValidationResult requestSaveBankAccount() { InputValidator.ValidationResult requestSaveBankAccount() {
InputValidator.ValidationResult result = validateInput(); InputValidator.ValidationResult result = validateInput();
if (result.isValid) { if (result.isValid) {
model.saveBankAccount(); delegate.saveBankAccount();
} }
return result; return result;
} }
void removeBankAccount() { void removeBankAccount() {
model.removeBankAccount(); delegate.removeBankAccount();
} }
void addCountryToAcceptedCountriesList() { void addCountryToAcceptedCountriesList() {
model.addCountryToAcceptedCountriesList(); delegate.addCountryToAcceptedCountriesList();
} }
void selectBankAccount(BankAccount bankAccount) { void selectBankAccount(BankAccount bankAccount) {
model.selectBankAccount(bankAccount); delegate.selectBankAccount(bankAccount);
} }
@ -188,27 +187,27 @@ class FiatAccountPM extends PresentationModel<FiatAccountModel> {
ObservableList<BankAccountType> getAllTypes() { ObservableList<BankAccountType> getAllTypes() {
return model.allTypes; return delegate.allTypes;
} }
ObservableList<BankAccount> getAllBankAccounts() { ObservableList<BankAccount> getAllBankAccounts() {
return model.allBankAccounts; return delegate.allBankAccounts;
} }
ObservableList<Currency> getAllCurrencies() { ObservableList<Currency> getAllCurrencies() {
return model.allCurrencies; return delegate.allCurrencies;
} }
ObservableList<Region> getAllRegions() { ObservableList<Region> getAllRegions() {
return model.allRegions; return delegate.allRegions;
} }
BooleanProperty getCountryNotInAcceptedCountriesList() { BooleanProperty getCountryNotInAcceptedCountriesList() {
return model.countryNotInAcceptedCountriesList; return delegate.countryNotInAcceptedCountriesList;
} }
ObservableList<Country> getAllCountriesFor(Region selectedRegion) { ObservableList<Country> getAllCountriesFor(Region selectedRegion) {
return model.getAllCountriesFor(selectedRegion); return delegate.getAllCountriesFor(selectedRegion);
} }
BankAccountNumberValidator getBankAccountNumberValidator() { BankAccountNumberValidator getBankAccountNumberValidator() {
@ -217,23 +216,23 @@ class FiatAccountPM extends PresentationModel<FiatAccountModel> {
void setType(BankAccountType type) { void setType(BankAccountType type) {
model.setType(type); delegate.setType(type);
validateInput(); validateInput();
} }
void setCountry(Country country) { void setCountry(Country country) {
model.setCountry(country); delegate.setCountry(country);
validateInput(); validateInput();
} }
void setCurrency(Currency currency) { void setCurrency(Currency currency) {
model.setCurrency(currency); delegate.setCurrency(currency);
validateInput(); validateInput();
} }
private void applyAllBankAccounts() { private void applyAllBankAccounts() {
if (model.allBankAccounts.isEmpty()) { if (delegate.allBankAccounts.isEmpty()) {
selectionPrompt.set("No bank account available"); selectionPrompt.set("No bank account available");
selectionDisable.set(true); selectionDisable.set(true);
} }
@ -244,23 +243,23 @@ class FiatAccountPM extends PresentationModel<FiatAccountModel> {
} }
private InputValidator.ValidationResult validateInput() { private InputValidator.ValidationResult validateInput() {
InputValidator.ValidationResult result = bankAccountNumberValidator.validate(model.title.get()); InputValidator.ValidationResult result = bankAccountNumberValidator.validate(delegate.title.get());
if (result.isValid) { if (result.isValid) {
result = bankAccountNumberValidator.validate(model.holderName.get()); result = bankAccountNumberValidator.validate(delegate.holderName.get());
if (result.isValid) { if (result.isValid) {
result = bankAccountNumberValidator.validate(model.primaryID.get()); result = bankAccountNumberValidator.validate(delegate.primaryID.get());
if (result.isValid) { if (result.isValid) {
result = bankAccountNumberValidator.validate(model.secondaryID.get()); result = bankAccountNumberValidator.validate(delegate.secondaryID.get());
if (result.isValid) { if (result.isValid) {
if (model.currency.get() == null) if (delegate.currency.get() == null)
result = new InputValidator.ValidationResult(false, result = new InputValidator.ValidationResult(false,
"You have not selected a currency"); "You have not selected a currency");
if (result.isValid) { if (result.isValid) {
if (model.country.get() == null) if (delegate.country.get() == null)
result = new InputValidator.ValidationResult(false, result = new InputValidator.ValidationResult(false,
"You have not selected a country of the payments account"); "You have not selected a country of the payments account");
if (result.isValid) { if (result.isValid) {
if (model.type.get() == null) if (delegate.type.get() == null)
result = new InputValidator.ValidationResult(false, result = new InputValidator.ValidationResult(false,
"You have not selected a payments method"); "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.arbitrator.Reputation;
import io.bitsquare.bank.BankAccount; import io.bitsquare.bank.BankAccount;
import io.bitsquare.bank.BankAccountType; 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.Country;
import io.bitsquare.locale.CountryUtil; import io.bitsquare.locale.CountryUtil;
import io.bitsquare.locale.CurrencyUtil; import io.bitsquare.locale.CurrencyUtil;
@ -51,7 +52,7 @@ import javafx.beans.property.StringProperty;
import javafx.collections.FXCollections; import javafx.collections.FXCollections;
import javafx.collections.ObservableList; import javafx.collections.ObservableList;
class IrcAccountModel extends UIModel { class IrcAccountModel implements Activatable, DataModel {
private final User user; private final User user;
private final AccountSettings accountSettings; private final AccountSettings accountSettings;
@ -82,10 +83,14 @@ class IrcAccountModel extends UIModel {
@Override @Override
public void activate() { public void activate() {
super.activate();
allBankAccounts.setAll(user.getBankAccounts()); allBankAccounts.setAll(user.getBankAccounts());
} }
@Override
public void deactivate() {
// no-op
}
void saveBankAccount() { void saveBankAccount() {
BankAccount bankAccount = new BankAccount(type.get(), BankAccount bankAccount = new BankAccount(type.get(),
currency.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.BankAccount;
import io.bitsquare.bank.BankAccountType; 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.BankAccountNumberValidator;
import io.bitsquare.gui.util.validation.InputValidator; import io.bitsquare.gui.util.validation.InputValidator;
import io.bitsquare.locale.BSResources; import io.bitsquare.locale.BSResources;
@ -37,7 +38,7 @@ import javafx.beans.property.StringProperty;
import javafx.collections.ObservableList; import javafx.collections.ObservableList;
import javafx.util.StringConverter; import javafx.util.StringConverter;
class IrcAccountPM extends PresentationModel<IrcAccountModel> { class IrcAccountPM extends ActivatableWithDelegate<IrcAccountModel> implements ViewModel {
private final InputValidator nickNameValidator; private final InputValidator nickNameValidator;
@ -64,13 +65,13 @@ class IrcAccountPM extends PresentationModel<IrcAccountModel> {
InputValidator.ValidationResult requestSaveBankAccount() { InputValidator.ValidationResult requestSaveBankAccount() {
InputValidator.ValidationResult result = validateInput(); InputValidator.ValidationResult result = validateInput();
if (result.isValid) { if (result.isValid) {
model.saveBankAccount(); delegate.saveBankAccount();
} }
return result; return result;
} }
ObservableList<BankAccount> getAllBankAccounts() { ObservableList<BankAccount> getAllBankAccounts() {
return model.allBankAccounts; return delegate.allBankAccounts;
} }
StringConverter<BankAccountType> getTypesConverter() { StringConverter<BankAccountType> getTypesConverter() {
@ -107,11 +108,11 @@ class IrcAccountPM extends PresentationModel<IrcAccountModel> {
ObservableList<BankAccountType> getAllTypes() { ObservableList<BankAccountType> getAllTypes() {
return model.allTypes; return delegate.allTypes;
} }
ObservableList<Currency> getAllCurrencies() { ObservableList<Currency> getAllCurrencies() {
return model.allCurrencies; return delegate.allCurrencies;
} }
InputValidator getNickNameValidator() { InputValidator getNickNameValidator() {
@ -120,24 +121,24 @@ class IrcAccountPM extends PresentationModel<IrcAccountModel> {
void setType(BankAccountType type) { void setType(BankAccountType type) {
model.setType(type); delegate.setType(type);
validateInput(); validateInput();
} }
void setCurrency(Currency currency) { void setCurrency(Currency currency) {
model.setCurrency(currency); delegate.setCurrency(currency);
validateInput(); validateInput();
} }
private InputValidator.ValidationResult validateInput() { private InputValidator.ValidationResult validateInput() {
InputValidator.ValidationResult result = nickNameValidator.validate(model.nickName.get()); InputValidator.ValidationResult result = nickNameValidator.validate(delegate.nickName.get());
if (model.currency.get() == null) if (delegate.currency.get() == null)
result = new InputValidator.ValidationResult(false, result = new InputValidator.ValidationResult(false,
"You have not selected a currency"); "You have not selected a currency");
if (result.isValid) { if (result.isValid) {
if (model.type.get() == null) if (delegate.type.get() == null)
result = new InputValidator.ValidationResult(false, result = new InputValidator.ValidationResult(false,
"You have not selected a payments method"); "You have not selected a payments method");
} }

View file

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

View file

@ -17,7 +17,7 @@
package io.bitsquare.gui.main.account.content.password; 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.MultiStepNavigation;
import io.bitsquare.gui.main.account.content.ContextAware; import io.bitsquare.gui.main.account.content.ContextAware;
import io.bitsquare.gui.main.help.Help; import io.bitsquare.gui.main.help.Help;
@ -36,10 +36,12 @@ import javafx.scene.layout.*;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; 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 static final Logger log = LoggerFactory.getLogger(PasswordViewCB.class);
private final PasswordPM model;
@FXML HBox buttonsHBox; @FXML HBox buttonsHBox;
@FXML Button saveButton, skipButton; @FXML Button saveButton, skipButton;
@FXML PasswordField oldPasswordField, passwordField, repeatedPasswordField; @FXML PasswordField oldPasswordField, passwordField, repeatedPasswordField;
@ -50,8 +52,8 @@ public class PasswordViewCB extends CachedViewCB<PasswordPM> implements ContextA
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
@Inject @Inject
private PasswordViewCB(PasswordPM presentationModel) { private PasswordViewCB(PasswordPM model) {
super(presentationModel); this.model = model;
} }
@ -63,28 +65,10 @@ public class PasswordViewCB extends CachedViewCB<PasswordPM> implements ContextA
public void initialize(URL url, ResourceBundle rb) { public void initialize(URL url, ResourceBundle rb) {
super.initialize(url, rb); super.initialize(url, rb);
passwordField.textProperty().bindBidirectional(presentationModel.passwordField); passwordField.textProperty().bindBidirectional(model.passwordField);
repeatedPasswordField.textProperty().bindBidirectional(presentationModel.repeatedPasswordField); 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();
} }
@ -105,14 +89,14 @@ public class PasswordViewCB extends CachedViewCB<PasswordPM> implements ContextA
@FXML @FXML
private void onSaved() { private void onSaved() {
boolean result = presentationModel.requestSavePassword(); boolean result = model.requestSavePassword();
if (result) { if (result) {
if (parent instanceof MultiStepNavigation) if (parent instanceof MultiStepNavigation)
((MultiStepNavigation) parent).nextStep(this); ((MultiStepNavigation) parent).nextStep(this);
} }
else { else {
// TODO use validating passwordTF // 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.FeePolicy;
import io.bitsquare.btc.WalletService; import io.bitsquare.btc.WalletService;
import io.bitsquare.btc.listeners.BalanceListener; import io.bitsquare.btc.listeners.BalanceListener;
import io.bitsquare.gui.UIModel; import io.bitsquare.gui.DataModel;
import io.bitsquare.persistence.Persistence; import io.bitsquare.persistence.Persistence;
import io.bitsquare.user.User; import io.bitsquare.user.User;
@ -45,7 +45,7 @@ import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
class RegistrationModel extends UIModel { class RegistrationModel implements DataModel {
private static final Logger log = LoggerFactory.getLogger(RegistrationModel.class); private static final Logger log = LoggerFactory.getLogger(RegistrationModel.class);
private final WalletService walletService; private final WalletService walletService;

View file

@ -18,7 +18,8 @@
package io.bitsquare.gui.main.account.content.registration; package io.bitsquare.gui.main.account.content.registration;
import io.bitsquare.btc.WalletService; 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.gui.util.BSFormatter;
import io.bitsquare.locale.BSResources; import io.bitsquare.locale.BSResources;
@ -35,7 +36,7 @@ import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty; import javafx.beans.property.StringProperty;
class RegistrationPM extends PresentationModel<RegistrationModel> { class RegistrationPM extends WithDelegate<RegistrationModel> implements ViewModel {
final BooleanProperty isPayButtonDisabled = new SimpleBooleanProperty(true); final BooleanProperty isPayButtonDisabled = new SimpleBooleanProperty(true);
final StringProperty requestPlaceOfferErrorMessage = new SimpleStringProperty(); final StringProperty requestPlaceOfferErrorMessage = new SimpleStringProperty();
@ -48,27 +49,27 @@ class RegistrationPM extends PresentationModel<RegistrationModel> {
@Inject @Inject
public RegistrationPM(RegistrationModel model, BSFormatter formatter) { public RegistrationPM(RegistrationModel delegate, BSFormatter formatter) {
super(model); super(delegate);
this.formatter = formatter; this.formatter = formatter;
if (model.getAddressEntry() != null) { if (delegate.getAddressEntry() != null) {
address.set(model.getAddressEntry().getAddress()); address.set(delegate.getAddressEntry().getAddress());
} }
model.isWalletFunded.addListener((ov, oldValue, newValue) -> { delegate.isWalletFunded.addListener((ov, oldValue, newValue) -> {
if (newValue) if (newValue)
validateInput(); validateInput();
}); });
validateInput(); validateInput();
model.payFeeSuccess.addListener((ov, oldValue, newValue) -> { delegate.payFeeSuccess.addListener((ov, oldValue, newValue) -> {
isPayButtonDisabled.set(newValue); isPayButtonDisabled.set(newValue);
showTransactionPublishedScreen.set(newValue); showTransactionPublishedScreen.set(newValue);
isPaymentSpinnerVisible.set(false); isPaymentSpinnerVisible.set(false);
}); });
model.payFeeErrorMessage.addListener((ov, oldValue, newValue) -> { delegate.payFeeErrorMessage.addListener((ov, oldValue, newValue) -> {
if (newValue != null) { if (newValue != null) {
requestPlaceOfferErrorMessage.set(newValue); requestPlaceOfferErrorMessage.set(newValue);
isPaymentSpinnerVisible.set(false); isPaymentSpinnerVisible.set(false);
@ -77,18 +78,18 @@ class RegistrationPM extends PresentationModel<RegistrationModel> {
} }
void payFee() { void payFee() {
model.payFeeErrorMessage.set(null); delegate.payFeeErrorMessage.set(null);
model.payFeeSuccess.set(false); delegate.payFeeSuccess.set(false);
isPayButtonDisabled.set(true); isPayButtonDisabled.set(true);
isPaymentSpinnerVisible.set(true); isPaymentSpinnerVisible.set(true);
model.payFee(); delegate.payFee();
} }
WalletService getWalletService() { WalletService getWalletService() {
return model.getWalletService(); return delegate.getWalletService();
} }
BSFormatter getFormatter() { BSFormatter getFormatter() {
@ -96,11 +97,11 @@ class RegistrationPM extends PresentationModel<RegistrationModel> {
} }
Coin getFeeAsCoin() { Coin getFeeAsCoin() {
return model.getFeeAsCoin(); return delegate.getFeeAsCoin();
} }
String getAddressAsString() { String getAddressAsString() {
return model.getAddressEntry() != null ? model.getAddressEntry().getAddress().toString() : ""; return delegate.getAddressEntry() != null ? delegate.getAddressEntry().getAddress().toString() : "";
} }
String getPaymentLabel() { String getPaymentLabel() {
@ -108,16 +109,16 @@ class RegistrationPM extends PresentationModel<RegistrationModel> {
} }
String getFeeAsString() { String getFeeAsString() {
return formatter.formatCoinWithCode(model.getFeeAsCoin()); return formatter.formatCoinWithCode(delegate.getFeeAsCoin());
} }
String getTransactionId() { String getTransactionId() {
return model.getTransactionId(); return delegate.getTransactionId();
} }
private void validateInput() { 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; package io.bitsquare.gui.main.account.content.registration;
import io.bitsquare.gui.CachedViewCB;
import io.bitsquare.gui.OverlayManager; import io.bitsquare.gui.OverlayManager;
import io.bitsquare.gui.ViewCB;
import io.bitsquare.gui.components.AddressTextField; import io.bitsquare.gui.components.AddressTextField;
import io.bitsquare.gui.components.BalanceTextField; import io.bitsquare.gui.components.BalanceTextField;
import io.bitsquare.gui.components.Popups; import io.bitsquare.gui.components.Popups;
@ -48,11 +48,12 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory; 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 static final Logger log = LoggerFactory.getLogger(RegistrationViewCB.class);
private final OverlayManager overlayManager; private final OverlayManager overlayManager;
private final RegistrationPM model;
@FXML TextField feeTextField; @FXML TextField feeTextField;
@FXML AddressTextField addressTextField; @FXML AddressTextField addressTextField;
@ -67,8 +68,8 @@ public class RegistrationViewCB extends CachedViewCB<RegistrationPM> implements
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
@Inject @Inject
private RegistrationViewCB(RegistrationPM presentationModel, OverlayManager overlayManager) { private RegistrationViewCB(RegistrationPM model, OverlayManager overlayManager) {
super(presentationModel); this.model = model;
this.overlayManager = overlayManager; this.overlayManager = overlayManager;
} }
@ -81,20 +82,20 @@ public class RegistrationViewCB extends CachedViewCB<RegistrationPM> implements
public void initialize(URL url, ResourceBundle rb) { public void initialize(URL url, ResourceBundle rb) {
super.initialize(url, rb); super.initialize(url, rb);
feeTextField.setText(presentationModel.getFeeAsString()); feeTextField.setText(model.getFeeAsString());
addressTextField.setAmountAsCoin(presentationModel.getFeeAsCoin()); addressTextField.setAmountAsCoin(model.getFeeAsCoin());
addressTextField.setPaymentLabel(presentationModel.getPaymentLabel()); addressTextField.setPaymentLabel(model.getPaymentLabel());
addressTextField.setAddress(presentationModel.getAddressAsString()); addressTextField.setAddress(model.getAddressAsString());
// TODO find better solution // TODO find better solution
addressTextField.setOverlayManager(overlayManager); addressTextField.setOverlayManager(overlayManager);
balanceTextField.setup(presentationModel.getWalletService(), presentationModel.address.get(), balanceTextField.setup(model.getWalletService(), model.address.get(),
presentationModel.getFormatter()); 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) { if (newValue != null) {
Popups.openErrorPopup(BSResources.get("shared.error"), Popups.openErrorPopup(BSResources.get("shared.error"),
BSResources.get("An error occurred when paying the registration fee"), 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.setProgress(newValue ? -1 : 0);
paymentSpinner.setVisible(newValue); paymentSpinner.setVisible(newValue);
}); });
presentationModel.showTransactionPublishedScreen.addListener((o, oldValue, newValue) -> { model.showTransactionPublishedScreen.addListener((o, oldValue, newValue) -> {
if (newValue) { if (newValue) {
overlayManager.blurContent(); 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 // ContextAware implementation
@ -181,7 +164,7 @@ public class RegistrationViewCB extends CachedViewCB<RegistrationPM> implements
@FXML @FXML
private void onPayFee() { private void onPayFee() {
presentationModel.payFee(); model.payFee();
} }
@FXML @FXML

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -17,7 +17,8 @@
package io.bitsquare.gui.main.settings.application; 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; import com.google.inject.Inject;
@ -25,7 +26,7 @@ import javafx.beans.property.BooleanProperty;
import javafx.beans.property.StringProperty; import javafx.beans.property.StringProperty;
import javafx.collections.ObservableList; import javafx.collections.ObservableList;
class PreferencesPM extends PresentationModel<PreferencesModel> { class PreferencesPM extends ActivatableWithDelegate<PreferencesModel> implements ViewModel {
@Inject @Inject
public PreferencesPM(PreferencesModel model) { public PreferencesPM(PreferencesModel model) {
@ -33,19 +34,19 @@ class PreferencesPM extends PresentationModel<PreferencesModel> {
} }
public ObservableList<String> getBtcDenominationItems() { public ObservableList<String> getBtcDenominationItems() {
return model.btcDenominations; return delegate.btcDenominations;
} }
BooleanProperty useAnimations() { BooleanProperty useAnimations() {
return model.useAnimations; return delegate.useAnimations;
} }
BooleanProperty useEffects() { BooleanProperty useEffects() {
return model.useEffects; return delegate.useEffects;
} }
StringProperty btcDenomination() { 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.FeePolicy;
import io.bitsquare.btc.WalletService; import io.bitsquare.btc.WalletService;
import io.bitsquare.btc.listeners.BalanceListener; 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.gui.util.BSFormatter;
import io.bitsquare.locale.Country; import io.bitsquare.locale.Country;
import io.bitsquare.offer.Direction; 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). * 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. * 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 static final Logger log = LoggerFactory.getLogger(CreateOfferModel.class);
private final TradeManager tradeManager; private final TradeManager tradeManager;
@ -151,8 +152,6 @@ class CreateOfferModel extends UIModel {
@Override @Override
public void activate() { public void activate() {
super.activate();
// might be changed after screen change // might be changed after screen change
if (accountSettings != null) { if (accountSettings != null) {
// set it here again to cover the case of an securityDeposit change after a screen change // 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() { void placeOffer() {
// data validation is done in the trade domain // data validation is done in the trade domain
tradeManager.requestPlaceOffer(offerId, tradeManager.requestPlaceOffer(offerId,

View file

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

View file

@ -18,7 +18,8 @@
package io.bitsquare.gui.main.trade.offerbook; package io.bitsquare.gui.main.trade.offerbook;
import io.bitsquare.bank.BankAccount; 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.gui.util.BSFormatter;
import io.bitsquare.locale.Country; import io.bitsquare.locale.Country;
import io.bitsquare.locale.CurrencyUtil; 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. * 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 static final Logger log = LoggerFactory.getLogger(OfferBookModel.class);
private final User user; private final User user;
@ -93,8 +94,6 @@ class OfferBookModel extends UIModel {
@Override @Override
public void activate() { public void activate() {
super.activate();
amountAsCoin.set(null); amountAsCoin.set(null);
priceAsFiat.set(null); priceAsFiat.set(null);
volumeAsFiat.set(null); volumeAsFiat.set(null);
@ -109,8 +108,6 @@ class OfferBookModel extends UIModel {
@Override @Override
public void deactivate() { public void deactivate() {
super.deactivate();
offerBook.removeClient(); offerBook.removeClient();
user.currentBankAccountProperty().removeListener(bankAccountChangeListener); user.currentBankAccountProperty().removeListener(bankAccountChangeListener);
btcCode.unbind(); btcCode.unbind();

View file

@ -17,7 +17,8 @@
package io.bitsquare.gui.main.trade.offerbook; 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.BSFormatter;
import io.bitsquare.gui.util.validation.InputValidator; import io.bitsquare.gui.util.validation.InputValidator;
import io.bitsquare.gui.util.validation.OptionalBtcValidator; import io.bitsquare.gui.util.validation.OptionalBtcValidator;
@ -35,7 +36,7 @@ import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty; import javafx.beans.property.StringProperty;
import javafx.collections.transformation.SortedList; import javafx.collections.transformation.SortedList;
class OfferBookPM extends PresentationModel<OfferBookModel> { class OfferBookPM extends ActivatableWithDelegate<OfferBookModel> implements ViewModel {
private final OptionalBtcValidator optionalBtcValidator; private final OptionalBtcValidator optionalBtcValidator;
private final BSFormatter formatter; private final BSFormatter formatter;
@ -50,17 +51,17 @@ class OfferBookPM extends PresentationModel<OfferBookModel> {
@Inject @Inject
public OfferBookPM(OfferBookModel model, OptionalFiatValidator optionalFiatValidator, public OfferBookPM(OfferBookModel delegate, OptionalFiatValidator optionalFiatValidator,
OptionalBtcValidator optionalBtcValidator, BSFormatter formatter) { OptionalBtcValidator optionalBtcValidator, BSFormatter formatter) {
super(model); super(delegate);
this.optionalFiatValidator = optionalFiatValidator; this.optionalFiatValidator = optionalFiatValidator;
this.optionalBtcValidator = optionalBtcValidator; this.optionalBtcValidator = optionalBtcValidator;
this.formatter = formatter; this.formatter = formatter;
btcCode.bind(model.btcCode); btcCode.bind(delegate.btcCode);
fiatCode.bind(model.fiatCode); fiatCode.bind(delegate.fiatCode);
restrictionsInfo.bind(model.restrictionsInfo); restrictionsInfo.bind(delegate.restrictionsInfo);
// Bidirectional bindings are used for all input fields: amount, price and volume // Bidirectional bindings are used for all input fields: amount, price and volume
// We do volume/amount calculation during input, so user has immediate feedback // 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) { if (isBtcInputValid(newValue).isValid) {
setAmountToModel(); setAmountToModel();
setPriceToModel(); setPriceToModel();
model.calculateVolume(); delegate.calculateVolume();
} }
}); });
@ -76,7 +77,7 @@ class OfferBookPM extends PresentationModel<OfferBookModel> {
if (isFiatInputValid(newValue).isValid) { if (isFiatInputValid(newValue).isValid) {
setAmountToModel(); setAmountToModel();
setPriceToModel(); setPriceToModel();
model.calculateVolume(); delegate.calculateVolume();
} }
}); });
@ -84,42 +85,42 @@ class OfferBookPM extends PresentationModel<OfferBookModel> {
if (isFiatInputValid(newValue).isValid) { if (isFiatInputValid(newValue).isValid) {
setPriceToModel(); setPriceToModel();
setVolumeToModel(); setVolumeToModel();
model.calculateAmount(); delegate.calculateAmount();
} }
}); });
// Binding with Bindings.createObjectBinding does not work because of bi-directional binding // 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))); (newValue)));
model.priceAsFiatProperty().addListener((ov, oldValue, newValue) -> price.set(formatter.formatFiat(newValue))); delegate.priceAsFiatProperty().addListener((ov, oldValue, newValue) -> price.set(formatter.formatFiat(newValue)));
model.volumeAsFiatProperty().addListener((ov, oldValue, newValue) -> volume.set(formatter.formatFiat delegate.volumeAsFiatProperty().addListener((ov, oldValue, newValue) -> volume.set(formatter.formatFiat
(newValue))); (newValue)));
} }
void removeOffer(Offer offer) { void removeOffer(Offer offer) {
model.removeOffer(offer); delegate.removeOffer(offer);
} }
boolean isTradable(Offer offer) { boolean isTradable(Offer offer) {
return model.isTradable(offer); return delegate.isTradable(offer);
} }
void setDirection(Direction direction) { void setDirection(Direction direction) {
model.setDirection(direction); delegate.setDirection(direction);
} }
SortedList<OfferBookListItem> getOfferList() { SortedList<OfferBookListItem> getOfferList() {
return model.getOfferList(); return delegate.getOfferList();
} }
boolean isRegistered() { boolean isRegistered() {
return model.isRegistered(); return delegate.isRegistered();
} }
boolean isMyOffer(Offer offer) { boolean isMyOffer(Offer offer) {
return model.isMyOffer(offer); return delegate.isMyOffer(offer);
} }
String getAmount(OfferBookListItem item) { String getAmount(OfferBookListItem item) {
@ -145,15 +146,15 @@ class OfferBookPM extends PresentationModel<OfferBookModel> {
} }
Direction getDirection() { Direction getDirection() {
return model.getDirection(); return delegate.getDirection();
} }
Coin getAmountAsCoin() { Coin getAmountAsCoin() {
return model.getAmountAsCoin(); return delegate.getAmountAsCoin();
} }
Fiat getPriceAsCoin() { Fiat getPriceAsCoin() {
return model.getPriceAsFiat(); return delegate.getPriceAsFiat();
} }
private InputValidator.ValidationResult isBtcInputValid(String input) { private InputValidator.ValidationResult isBtcInputValid(String input) {
@ -165,15 +166,15 @@ class OfferBookPM extends PresentationModel<OfferBookModel> {
} }
private void setAmountToModel() { private void setAmountToModel() {
model.setAmount(formatter.parseToCoinWith4Decimals(amount.get())); delegate.setAmount(formatter.parseToCoinWith4Decimals(amount.get()));
} }
private void setPriceToModel() { private void setPriceToModel() {
model.setPrice(formatter.parseToFiatWith2Decimals(price.get())); delegate.setPrice(formatter.parseToFiatWith2Decimals(price.get()));
} }
private void setVolumeToModel() { 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.FeePolicy;
import io.bitsquare.btc.WalletService; import io.bitsquare.btc.WalletService;
import io.bitsquare.btc.listeners.BalanceListener; 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.offer.Offer;
import io.bitsquare.persistence.Persistence; import io.bitsquare.persistence.Persistence;
import io.bitsquare.settings.Preferences; 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). * 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. * 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 static final Logger log = LoggerFactory.getLogger(TakeOfferModel.class);
private final TradeManager tradeManager; private final TradeManager tradeManager;
@ -92,16 +93,11 @@ class TakeOfferModel extends UIModel {
@Override @Override
public void activate() { public void activate() {
super.activate();
btcCode.bind(preferences.btcDenominationProperty()); btcCode.bind(preferences.btcDenominationProperty());
} }
@SuppressWarnings("EmptyMethod")
@Override @Override
public void deactivate() { public void deactivate() {
super.deactivate();
btcCode.unbind(); btcCode.unbind();
} }

View file

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

View file

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