Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multilanguage #1500

Draft
wants to merge 4 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 50 additions & 4 deletions src/main/java/com/sparrowwallet/sparrow/AppController.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
import com.sparrowwallet.sparrow.control.*;
import com.sparrowwallet.sparrow.event.*;
import com.sparrowwallet.sparrow.glyphfont.FontAwesome5;
import com.sparrowwallet.sparrow.i18n.Language;
import com.sparrowwallet.sparrow.i18n.LanguagesManager;
import com.sparrowwallet.sparrow.io.*;
import com.sparrowwallet.sparrow.io.bbqr.BBQR;
import com.sparrowwallet.sparrow.io.bbqr.BBQRType;
Expand Down Expand Up @@ -138,6 +140,12 @@ public class AppController implements Initializable {
@FXML
private ToggleGroup theme;

@FXML
private ToggleGroup languages;

@FXML
private Menu languagesMenu;

@FXML
private CheckMenuItem openWalletsInNewWindows;
private static final BooleanProperty openWalletsInNewWindowsProperty = new SimpleBooleanProperty();
Expand Down Expand Up @@ -373,6 +381,8 @@ void initializeView() {
selectedThemeToggle.ifPresent(toggle -> theme.selectToggle(toggle));
setTheme(null);

prepareLanguages();

openWalletsInNewWindowsProperty.set(Config.get().isOpenWalletsInNewWindows());
openWalletsInNewWindows.selectedProperty().bindBidirectional(openWalletsInNewWindowsProperty);
hideEmptyUsedAddressesProperty.set(Config.get().isHideEmptyUsedAddresses());
Expand Down Expand Up @@ -430,6 +440,27 @@ void initializeView() {
setNetworkLabel();
}

private void prepareLanguages() {
Language[] languagesList = Language.values();
for(Language language : languagesList) {
RadioMenuItem languageItem = new RadioMenuItem(LanguagesManager.getMessage("language." + language.getCode()));
languageItem.setMnemonicParsing(false);
languageItem.setToggleGroup(languages);
languageItem.setOnAction(this::setLanguage);
languageItem.setUserData(language);
languagesMenu.getItems().add(languageItem);
}

Language configLanguage = Config.get().getLanguage();
if(configLanguage == null) {
configLanguage = LanguagesManager.DEFAULT_LANGUAGE;
Config.get().setLanguage(configLanguage);
}
final Language selectedLanguage = configLanguage;
Optional<Toggle> selectedLanguageToggle = languages.getToggles().stream().filter(toggle -> selectedLanguage.equals(toggle.getUserData())).findFirst();
selectedLanguageToggle.ifPresent(toggle -> languages.selectToggle(toggle));
}

private void registerShortcuts() {
org.controlsfx.tools.Platform platform = org.controlsfx.tools.Platform.getCurrent();
if(platform == org.controlsfx.tools.Platform.OSX) {
Expand Down Expand Up @@ -488,7 +519,7 @@ private void setNetworkLabel() {
}

public void showIntroduction(ActionEvent event) {
WelcomeDialog welcomeDialog = new WelcomeDialog();
WelcomeDialog welcomeDialog = new WelcomeDialog(false);
welcomeDialog.initOwner(rootStack.getScene().getWindow());
Optional<Mode> optionalMode = welcomeDialog.showAndWait();
if(optionalMode.isPresent() && optionalMode.get().equals(Mode.ONLINE)) {
Expand Down Expand Up @@ -996,13 +1027,19 @@ public void restartInHome(ActionEvent event) {
}
}

public void restart(ActionEvent event) {
restart(event, (Network) null);
}

public void restart(ActionEvent event, Network network) {
if(System.getProperty(JPACKAGE_APP_PATH) == null) {
throw new IllegalStateException("Property " + JPACKAGE_APP_PATH + " is not present");
}

Args args = getRestartArgs();
args.network = network;
if(network != null) {
args.network = network;
}
restart(event, args);
}

Expand Down Expand Up @@ -1760,7 +1797,7 @@ public WalletForm addWalletSubTab(TabPane subTabs, Storage storage, Wallet walle
subTabLabel.setTooltip(new Tooltip(label));
}
subTab.setGraphic(subTabLabel);
FXMLLoader walletLoader = new FXMLLoader(getClass().getResource("wallet/wallet.fxml"));
FXMLLoader walletLoader = new FXMLLoader(getClass().getResource("wallet/wallet.fxml"), LanguagesManager.getResourceBundle());
subTab.setContent(walletLoader.load());
WalletController controller = walletLoader.getController();

Expand Down Expand Up @@ -2337,6 +2374,15 @@ public void setTheme(ActionEvent event) {
EventManager.get().post(new ThemeChangedEvent(selectedTheme));
}

public void setLanguage(ActionEvent event) {
Language selectedLanguage = (Language)languages.getSelectedToggle().getUserData();
if(Config.get().getLanguage() != selectedLanguage) {
Config.get().setLanguage(selectedLanguage);
}

restart(event);
}

private void serverToggleStartAnimation() {
Node thumbArea = serverToggle.lookup(".thumb-area");
if(thumbArea != null) {
Expand Down Expand Up @@ -3135,4 +3181,4 @@ public void walletConfigChanged(WalletConfigChangedEvent event) {
}
}
}
}
}
3 changes: 2 additions & 1 deletion src/main/java/com/sparrowwallet/sparrow/AppServices.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import com.sparrowwallet.drongo.wallet.*;
import com.sparrowwallet.sparrow.control.WalletPasswordDialog;
import com.sparrowwallet.sparrow.glyphfont.FontAwesome5;
import com.sparrowwallet.sparrow.i18n.LanguagesManager;
import com.sparrowwallet.sparrow.net.Auth47;
import com.sparrowwallet.drongo.protocol.BlockHeader;
import com.sparrowwallet.drongo.protocol.ScriptType;
Expand Down Expand Up @@ -551,7 +552,7 @@ public static HostAndPort getTorProxy() {

public static AppController newAppWindow(Stage stage) {
try {
FXMLLoader appLoader = new FXMLLoader(AppServices.class.getResource("app.fxml"));
FXMLLoader appLoader = new FXMLLoader(AppServices.class.getResource("app.fxml"), LanguagesManager.getResourceBundle());
Parent root = appLoader.load();
AppController appController = appLoader.getController();

Expand Down
11 changes: 10 additions & 1 deletion src/main/java/com/sparrowwallet/sparrow/SparrowDesktop.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
import com.sparrowwallet.sparrow.control.WalletIcon;
import com.sparrowwallet.sparrow.glyphfont.FontAwesome5;
import com.sparrowwallet.sparrow.glyphfont.FontAwesome5Brands;
import com.sparrowwallet.sparrow.i18n.Language;
import com.sparrowwallet.sparrow.i18n.LanguagesManager;
import com.sparrowwallet.sparrow.io.Config;
import com.sparrowwallet.sparrow.io.Storage;
import com.sparrowwallet.sparrow.net.PublicElectrumServer;
Expand Down Expand Up @@ -53,7 +55,7 @@ public void start(Stage stage) throws Exception {
boolean createNewWallet = false;
Mode mode = Config.get().getMode();
if(mode == null) {
WelcomeDialog welcomeDialog = new WelcomeDialog();
WelcomeDialog welcomeDialog = new WelcomeDialog(true);
Optional<Mode> optionalMode = welcomeDialog.showAndWait();
if(optionalMode.isPresent()) {
mode = optionalMode.get();
Expand Down Expand Up @@ -87,6 +89,13 @@ public void start(Stage stage) throws Exception {
mainStage.setHeight(Config.get().getAppHeight());
}

Language configLanguage = Config.get().getLanguage();
if(configLanguage == null) {
configLanguage = LanguagesManager.DEFAULT_LANGUAGE;
Config.get().setLanguage(configLanguage);
}
LanguagesManager.loadLanguage(configLanguage.getCode());

AppController appController = AppServices.newAppWindow(stage);

final boolean showNewWallet = createNewWallet;
Expand Down
85 changes: 67 additions & 18 deletions src/main/java/com/sparrowwallet/sparrow/WelcomeController.java
Original file line number Diff line number Diff line change
@@ -1,22 +1,26 @@
package com.sparrowwallet.sparrow;

import com.sparrowwallet.sparrow.control.UnlabeledToggleSwitch;
import com.sparrowwallet.sparrow.event.LanguageChangedInWelcomeEvent;
import com.sparrowwallet.sparrow.i18n.Language;
import com.sparrowwallet.sparrow.i18n.LanguagesManager;
import com.sparrowwallet.sparrow.io.Config;
import javafx.animation.PauseTransition;
import javafx.application.Platform;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.event.ActionEvent;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.Event;
import javafx.event.EventHandler;
import javafx.event.EventType;
import javafx.fxml.FXML;
import javafx.scene.control.ComboBox;
import javafx.scene.control.Tooltip;
import javafx.scene.input.MouseButton;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.VBox;
import javafx.util.Duration;
import javafx.util.StringConverter;
import org.controlsfx.control.StatusBar;

import java.util.Arrays;
import java.util.List;

public class WelcomeController {
@FXML
private VBox welcomeBox;
Expand All @@ -36,10 +40,13 @@ public class WelcomeController {
@FXML
private StatusBar serverStatus;

@FXML
private ComboBox<Language> languages;

@FXML
private UnlabeledToggleSwitch serverToggle;

public void initializeView() {
public void initializeView(boolean isFirstExecution) {
step1.managedProperty().bind(step1.visibleProperty());
step2.managedProperty().bind(step2.visibleProperty());
step3.managedProperty().bind(step3.visibleProperty());
Expand All @@ -50,14 +57,51 @@ public void initializeView() {
step4.setVisible(false);

welcomeBox.getStyleClass().add("offline");
serverStatus.setText("Offline");
serverStatus.setText(LanguagesManager.getMessage("welcome.offline"));
serverToggle.addEventFilter(MouseEvent.MOUSE_RELEASED, Event::consume);
Tooltip tooltip = new Tooltip("Demonstration only - you are not connected!");
Tooltip tooltip = new Tooltip(LanguagesManager.getMessage("welcome.offline.tooltip"));
tooltip.setShowDelay(Duration.ZERO);
serverToggle.setTooltip(tooltip);
serverToggle.selectedProperty().addListener((observable, oldValue, newValue) -> {
serverStatus.setText(newValue ? "Connected (demonstration only)" : "Offline");
serverStatus.setText(newValue ? LanguagesManager.getMessage("welcome.server-status.online") : LanguagesManager.getMessage("welcome.offline"));
});

if(isFirstExecution) {
languages.setItems(getLanguagesList());
languages.setConverter(new StringConverter<>() {
@Override
public String toString(Language language) {
if(language != null) {
return LanguagesManager.getMessage("language." + language.getCode());
} else {
return null;
}
}

@Override
public Language fromString(String code) {
return Language.getFromCode(code);
}
});

Language configuredLanguage = Config.get().getLanguage();
if(configuredLanguage != null) {
languages.setValue(configuredLanguage);
} else {
languages.setValue(LanguagesManager.DEFAULT_LANGUAGE);
}

languages.valueProperty().addListener((observable, oldValue, newValue) -> {
if(Config.get().getLanguage() != newValue) {
Config.get().setLanguage(newValue);
LanguagesManager.loadLanguage(newValue.getCode());

EventManager.get().post(new LanguageChangedInWelcomeEvent(newValue));
}
});
} else {
languages.setVisible(false);
}
}

public boolean next() {
Expand All @@ -69,7 +113,7 @@ public boolean next() {
PauseTransition wait = new PauseTransition(Duration.millis(200));
wait.setOnFinished((e) -> {
serverToggle.setSelected(true);
serverStatus.setText("Connected to a Public Server (demonstration only)");
serverStatus.setText(LanguagesManager.getMessage("welcome.server-status.online.public-server"));
});
wait.play();
return true;
Expand All @@ -81,7 +125,7 @@ public boolean next() {
welcomeBox.getStyleClass().clear();
welcomeBox.getStyleClass().add("bitcoin-core");
serverToggle.setSelected(true);
serverStatus.setText("Connected to Bitcoin Core (demonstration only)");
serverStatus.setText(LanguagesManager.getMessage("welcome.server-status.online.bitcoin-core"));
return true;
}

Expand All @@ -91,7 +135,7 @@ public boolean next() {
welcomeBox.getStyleClass().clear();
welcomeBox.getStyleClass().add("private-electrum");
serverToggle.setSelected(true);
serverStatus.setText("Connected to a Private Electrum Server (demonstration only)");
serverStatus.setText(LanguagesManager.getMessage("welcome.server-status.online.private-electrum"));
}

return false;
Expand All @@ -106,7 +150,7 @@ public boolean back() {
PauseTransition wait = new PauseTransition(Duration.millis(200));
wait.setOnFinished((e) -> {
serverToggle.setSelected(false);
serverStatus.setText("Offline");
serverStatus.setText(LanguagesManager.getMessage("welcome.offline"));
});
wait.play();
return false;
Expand All @@ -118,7 +162,7 @@ public boolean back() {
welcomeBox.getStyleClass().clear();
welcomeBox.getStyleClass().add("public-electrum");
serverToggle.setSelected(true);
serverStatus.setText("Connected to a Public Server (demonstration only)");
serverStatus.setText(LanguagesManager.getMessage("welcome.server-status.online.public-server"));
return true;
}

Expand All @@ -128,10 +172,15 @@ public boolean back() {
welcomeBox.getStyleClass().clear();
welcomeBox.getStyleClass().add("bitcoin-core");
serverToggle.setSelected(true);
serverStatus.setText("Connected to Bitcoin Core (demonstration only)");
serverStatus.setText(LanguagesManager.getMessage("welcome.server-status.online.bitcoin-core"));
return true;
}

return false;
}
}

private ObservableList<Language> getLanguagesList() {
List<Language> languages = Arrays.asList(Language.values());
return FXCollections.observableList(languages);
}
}
Loading