diff --git a/README.i18n b/README.i18n new file mode 100644 index 00000000..2b913f7d --- /dev/null +++ b/README.i18n @@ -0,0 +1,45 @@ +The Monero command line tools can be translated in various languages. +In order to use the same translation workflow as the future GUI, they +use Qt Linguist translation files. However, to avoid the dependencies +on Qt this normally implies, they use a custom loader to read those +files at runtime. In order to update, or build translations files, you +do need to have Qt tools installed, however. For translating, you need +either the Qt Linguist GUI, or another tool that supports Qt ts files, +such as Transifex. To run, you do not need anything Qt. + +To update ts files after changing source code: + + ./utils/translations/update-translations.sh + +To add a new language, eg Spanish (ISO code es): + + cp transations/monero.ts transations/monero_es.ts + +To edit translations for Spanish: + + linguist translations/monero_es.ts + +To build translations after modiying them: + + ./utils/translations/build-translations.sh + +To test a translation: + + LANG=es ./build/release/bin/simplewallet + +To add new translatable sources in the source: + + Use the tr(string) function if possible. If the code is in a class, + and this class doesn't already have a tr() static function, add one, + which uses a context named after what lupdate uses for the context, + usually the fully qualified class name (eg, cryptonote::simple_wallet). + If you need to use tr in code that's not in a class, you can use the + fully qualified version (eg, simple_wallet::tr) of the one matching + the context you want. + Use QT_TRANSLATE_NOOP(string) if you want to specify a context manually. + +If you're getting messages of the form: + + Class 'cryptonote::simple_wallet' lacks Q_OBJECT macro + +all is fine, we don't actually need that here. diff --git a/README.md b/README.md index 1945408b..e2ba191d 100644 --- a/README.md +++ b/README.md @@ -167,3 +167,8 @@ Dependencies: Doxygen 1.8.0 or later, Graphviz 2.28 or later (optional). * To build, change to the root of the source code directory, and run `doxygen Doxyfile` * If you have installed Graphviz, you can also generate in-doc diagrams by instead running `HAVE_DOT=YES doxygen Doxyfile` * The output will be built in doc/html/ + +## Internationalization + +See README.i18n + diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index 620e1add..b1db006d 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -30,7 +30,8 @@ set(common_sources base58.cpp command_line.cpp dns_utils.cpp - util.cpp) + util.cpp + i18n.cpp) set(common_headers) @@ -46,7 +47,8 @@ set(common_private_headers scoped_message_writer.h unordered_containers_boost_serialization.h util.h - varint.h) + varint.h + i18n.h) bitmonero_private_headers(common ${common_private_headers}) diff --git a/src/common/i18n.h b/src/common/i18n.h new file mode 100644 index 00000000..2aeac228 --- /dev/null +++ b/src/common/i18n.h @@ -0,0 +1,36 @@ +// Copyright (c) 2014-2015, The Monero Project +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without modification, are +// permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of +// conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list +// of conditions and the following disclaimer in the documentation and/or other +// materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be +// used to endorse or promote products derived from this software without specific +// prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#pragma once + +#define QT_TRANSLATE_NOOP(context,str) i18n_translate(str,context) + +int i18n_set_language(const char *directory, const char *base); +const char *i18n_translate(const char *str, const std::string &context); +static inline std::string get_default_i18n_context() { return std::string(); } +static inline const char *tr(const char *str) { return i18n_translate(str,get_default_i18n_context()); } diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp index dee53c47..da5be17e 100644 --- a/src/simplewallet/simplewallet.cpp +++ b/src/simplewallet/simplewallet.cpp @@ -40,7 +40,9 @@ #include #include #include +#include #include "include_base_utils.h" +#include "common/i18n.h" #include "common/command_line.h" #include "common/util.h" #include "p2p/net_node.h" @@ -65,6 +67,7 @@ using namespace cryptonote; using boost::lexical_cast; namespace po = boost::program_options; namespace bf = boost::filesystem; +typedef cryptonote::simple_wallet sw; #define EXTENDED_LOGS_FILE "wallet_details.log" @@ -74,20 +77,20 @@ unsigned int epee::g_test_dbg_lock_sleep = 0; namespace { - const command_line::arg_descriptor arg_wallet_file = {"wallet-file", "Use wallet ", ""}; - const command_line::arg_descriptor arg_generate_new_wallet = {"generate-new-wallet", "Generate new wallet and save it to or
.wallet by default", ""}; - const command_line::arg_descriptor arg_generate_from_view_key = {"generate-from-view-key", "Generate wallet from (address:viewkey:filename) and save it to ", ""}; - const command_line::arg_descriptor arg_daemon_address = {"daemon-address", "Use daemon instance at :", ""}; - const command_line::arg_descriptor arg_daemon_host = {"daemon-host", "Use daemon instance at host instead of localhost", ""}; - const command_line::arg_descriptor arg_password = {"password", "Wallet password", "", true}; - const command_line::arg_descriptor arg_electrum_seed = {"electrum-seed", "Specify electrum seed for wallet recovery/creation", ""}; - const command_line::arg_descriptor arg_restore_deterministic_wallet = {"restore-deterministic-wallet", "Recover wallet using electrum-style mnemonic", false}; - const command_line::arg_descriptor arg_non_deterministic = {"non-deterministic", "creates non-deterministic view and spend keys", false}; - const command_line::arg_descriptor arg_daemon_port = {"daemon-port", "Use daemon instance at port instead of 8081", 0}; + const command_line::arg_descriptor arg_wallet_file = {"wallet-file", sw::tr("Use wallet "), ""}; + const command_line::arg_descriptor arg_generate_new_wallet = {"generate-new-wallet", sw::tr("Generate new wallet and save it to or
.wallet by default"), ""}; + const command_line::arg_descriptor arg_generate_from_view_key = {"generate-from-view-key", sw::tr("Generate wallet from (address:viewkey:filename) and save it to "), ""}; + const command_line::arg_descriptor arg_daemon_address = {"daemon-address", sw::tr("Use daemon instance at :"), ""}; + const command_line::arg_descriptor arg_daemon_host = {"daemon-host", sw::tr("Use daemon instance at host instead of localhost"), ""}; + const command_line::arg_descriptor arg_password = {"password", sw::tr("Wallet password"), "", true}; + const command_line::arg_descriptor arg_electrum_seed = {"electrum-seed", sw::tr("Specify electrum seed for wallet recovery/creation"), ""}; + const command_line::arg_descriptor arg_restore_deterministic_wallet = {"restore-deterministic-wallet", sw::tr("Recover wallet using electrum-style mnemonic"), false}; + const command_line::arg_descriptor arg_non_deterministic = {"non-deterministic", sw::tr("creates non-deterministic view and spend keys"), false}; + const command_line::arg_descriptor arg_daemon_port = {"daemon-port", sw::tr("Use daemon instance at port instead of 8081"), 0}; const command_line::arg_descriptor arg_log_level = {"log-level", "", LOG_LEVEL_0}; - const command_line::arg_descriptor arg_log_file = {"log-file", "Specify log file", ""}; - const command_line::arg_descriptor arg_testnet = {"testnet", "Used to deploy test nets. The daemon must be launched with --testnet flag", false}; - const command_line::arg_descriptor arg_restricted = {"restricted-rpc", "Restricts RPC to view only commands", false}; + const command_line::arg_descriptor arg_log_file = {"log-file", sw::tr("Specify log file"), ""}; + const command_line::arg_descriptor arg_testnet = {"testnet", sw::tr("Used to deploy test nets. The daemon must be launched with --testnet flag"), false}; + const command_line::arg_descriptor arg_restricted = {"restricted-rpc", sw::tr("Restricts RPC to view only commands"), false}; const command_line::arg_descriptor< std::vector > arg_command = {"command", ""}; @@ -98,7 +101,7 @@ namespace { if (status == CORE_RPC_STATUS_BUSY) { - err = "daemon is busy. Please try later"; + err = sw::tr("daemon is busy. Please try later"); } else if (status != CORE_RPC_STATUS_OK) { @@ -107,7 +110,7 @@ namespace } else { - err = "possible lost connection to daemon"; + err = sw::tr("possible lost connection to daemon"); } return err; } @@ -188,7 +191,7 @@ namespace message_writer fail_msg_writer() { - return message_writer(epee::log_space::console_color_red, true, "Error: ", LOG_LEVEL_0); + return message_writer(epee::log_space::console_color_red, true, sw::tr("Error: "), LOG_LEVEL_0); } } @@ -196,7 +199,7 @@ namespace std::string simple_wallet::get_commands_str() { std::stringstream ss; - ss << "Commands: " << ENDL; + ss << tr("Commands: ") << ENDL; std::string usage = m_cmd_binder.get_usage(); boost::replace_all(usage, "\n", "\n "); usage.insert(0, " "); @@ -227,7 +230,7 @@ bool simple_wallet::seed(const std::vector &args/* = std::vectorwatch_only()) { - fail_msg_writer() << "This wallet is watch-only and cannot have a seed."; + fail_msg_writer() << tr("This wallet is watch-only and cannot have a seed."); return true; } if (m_wallet->is_deterministic()) @@ -247,7 +250,7 @@ bool simple_wallet::seed(const std::vector &args/* = std::vector &args/* = s bool success = false; if (m_wallet->watch_only()) { - fail_msg_writer() << "This wallet is watch-only and doesn't have a seed."; + fail_msg_writer() << tr("This wallet is watch-only and doesn't have a seed."); return true; } if (!m_wallet->is_deterministic()) { - fail_msg_writer() << "This wallet is non-deterministic and doesn't have a seed."; + fail_msg_writer() << tr("This wallet is non-deterministic and doesn't have a seed."); return true; } tools::password_container pwd_container; success = pwd_container.read_password(); if (!success) { - fail_msg_writer() << "failed to read wallet password"; + fail_msg_writer() << tr("failed to read wallet password"); return true; } @@ -277,7 +280,7 @@ bool simple_wallet::seed_set_language(const std::vector &args/* = s success = m_wallet->verify_password(pwd_container.password()); if (!success) { - fail_msg_writer() << "invalid password"; + fail_msg_writer() << tr("invalid password"); return true; } @@ -297,33 +300,33 @@ simple_wallet::simple_wallet() : m_daemon_port(0) , m_refresh_progress_reporter(*this) { - m_cmd_binder.set_handler("start_mining", boost::bind(&simple_wallet::start_mining, this, _1), "start_mining [] - Start mining in daemon"); - m_cmd_binder.set_handler("stop_mining", boost::bind(&simple_wallet::stop_mining, this, _1), "Stop mining in daemon"); - m_cmd_binder.set_handler("save_bc", boost::bind(&simple_wallet::save_bc, this, _1), "Save current blockchain data"); - m_cmd_binder.set_handler("refresh", boost::bind(&simple_wallet::refresh, this, _1), "Resynchronize transactions and balance"); - m_cmd_binder.set_handler("balance", boost::bind(&simple_wallet::show_balance, this, _1), "Show current wallet balance"); - m_cmd_binder.set_handler("incoming_transfers", boost::bind(&simple_wallet::show_incoming_transfers, this, _1), "incoming_transfers [available|unavailable] - Show incoming transfers - all of them or filter them by availability"); - m_cmd_binder.set_handler("payments", boost::bind(&simple_wallet::show_payments, this, _1), "payments [ ... ] - Show payments , ... "); - m_cmd_binder.set_handler("bc_height", boost::bind(&simple_wallet::show_blockchain_height, this, _1), "Show blockchain height"); - m_cmd_binder.set_handler("transfer", boost::bind(&simple_wallet::transfer, this, _1), "transfer [] [ ... ] [payment_id] - Transfer ,... to ,... , respectively. is the number of transactions yours is indistinguishable from (from 0 to maximum available)"); - m_cmd_binder.set_handler("sweep_dust", boost::bind(&simple_wallet::sweep_dust, this, _1), "Send all dust outputs to the same address with mixin 0"); - m_cmd_binder.set_handler("set_log", boost::bind(&simple_wallet::set_log, this, _1), "set_log - Change current log detalization level, is a number 0-4"); - m_cmd_binder.set_handler("address", boost::bind(&simple_wallet::print_address, this, _1), "Show current wallet public address"); - m_cmd_binder.set_handler("integrated_address", boost::bind(&simple_wallet::print_integrated_address, this, _1), "Convert a payment ID to an integrated address for the current wallet public address (no arguments use a random payment ID), or display standard addres and payment ID corresponding to an integrated addres"); - m_cmd_binder.set_handler("save", boost::bind(&simple_wallet::save, this, _1), "Save wallet synchronized data"); - m_cmd_binder.set_handler("save_watch_only", boost::bind(&simple_wallet::save_watch_only, this, _1), "Save watch only keys file"); - m_cmd_binder.set_handler("viewkey", boost::bind(&simple_wallet::viewkey, this, _1), "Get viewkey"); - m_cmd_binder.set_handler("spendkey", boost::bind(&simple_wallet::spendkey, this, _1), "Get spendkey"); - m_cmd_binder.set_handler("seed", boost::bind(&simple_wallet::seed, this, _1), "Get deterministic seed"); - m_cmd_binder.set_handler("set", boost::bind(&simple_wallet::set_variable, this, _1), "available options: seed language - Set wallet seed langage"); - m_cmd_binder.set_handler("help", boost::bind(&simple_wallet::help, this, _1), "Show this help"); + m_cmd_binder.set_handler("start_mining", boost::bind(&simple_wallet::start_mining, this, _1), tr("start_mining [] - Start mining in daemon")); + m_cmd_binder.set_handler("stop_mining", boost::bind(&simple_wallet::stop_mining, this, _1), tr("Stop mining in daemon")); + m_cmd_binder.set_handler("save_bc", boost::bind(&simple_wallet::save_bc, this, _1), tr("Save current blockchain data")); + m_cmd_binder.set_handler("refresh", boost::bind(&simple_wallet::refresh, this, _1), tr("Resynchronize transactions and balance")); + m_cmd_binder.set_handler("balance", boost::bind(&simple_wallet::show_balance, this, _1), tr("Show current wallet balance")); + m_cmd_binder.set_handler("incoming_transfers", boost::bind(&simple_wallet::show_incoming_transfers, this, _1), tr("incoming_transfers [available|unavailable] - Show incoming transfers - all of them or filter them by availability")); + m_cmd_binder.set_handler("payments", boost::bind(&simple_wallet::show_payments, this, _1), tr("payments [ ... ] - Show payments , ... ")); + m_cmd_binder.set_handler("bc_height", boost::bind(&simple_wallet::show_blockchain_height, this, _1), tr("Show blockchain height")); + m_cmd_binder.set_handler("transfer", boost::bind(&simple_wallet::transfer, this, _1), tr("transfer [] [ ... ] [payment_id] - Transfer ,... to ,... , respectively. is the number of transactions yours is indistinguishable from (from 0 to maximum available)")); + m_cmd_binder.set_handler("sweep_dust", boost::bind(&simple_wallet::sweep_dust, this, _1), tr("Send all dust outputs to the same address with mixin 0")); + m_cmd_binder.set_handler("set_log", boost::bind(&simple_wallet::set_log, this, _1), tr("set_log - Change current log detalization level, is a number 0-4")); + m_cmd_binder.set_handler("address", boost::bind(&simple_wallet::print_address, this, _1), tr("Show current wallet public address")); + m_cmd_binder.set_handler("integrated_address", boost::bind(&simple_wallet::print_integrated_address, this, _1), tr("Convert a payment ID to an integrated address for the current wallet public address (no arguments use a random payment ID), or display standard addres and payment ID corresponding to an integrated addres")); + m_cmd_binder.set_handler("save", boost::bind(&simple_wallet::save, this, _1), tr("Save wallet synchronized data")); + m_cmd_binder.set_handler("save_watch_only", boost::bind(&simple_wallet::save_watch_only, this, _1), tr("Save watch only keys file")); + m_cmd_binder.set_handler("viewkey", boost::bind(&simple_wallet::viewkey, this, _1), tr("Get viewkey")); + m_cmd_binder.set_handler("spendkey", boost::bind(&simple_wallet::spendkey, this, _1), tr("Get spendkey")); + m_cmd_binder.set_handler("seed", boost::bind(&simple_wallet::seed, this, _1), tr("Get deterministic seed")); + m_cmd_binder.set_handler("set", boost::bind(&simple_wallet::set_variable, this, _1), tr("available options: seed language - Set wallet seed langage")); + m_cmd_binder.set_handler("help", boost::bind(&simple_wallet::help, this, _1), tr("Show this help")); } //---------------------------------------------------------------------------------------------------- bool simple_wallet::set_variable(const std::vector &args) { if (args.empty()) { - fail_msg_writer() << "set: needs an argument. available options: seed"; + fail_msg_writer() << tr("set: needs an argument. available options: seed"); return true; } else @@ -332,7 +335,7 @@ bool simple_wallet::set_variable(const std::vector &args) { if (args.size() == 1) { - fail_msg_writer() << "set seed: needs an argument. available options: language"; + fail_msg_writer() << tr("set seed: needs an argument. available options: language"); return true; } else if (args[1] == "language") @@ -344,7 +347,7 @@ bool simple_wallet::set_variable(const std::vector &args) } } } - fail_msg_writer() << "set: unrecognized argument(s)"; + fail_msg_writer() << tr("set: unrecognized argument(s)"); return true; } //---------------------------------------------------------------------------------------------------- @@ -352,18 +355,18 @@ bool simple_wallet::set_log(const std::vector &args) { if(args.size() != 1) { - fail_msg_writer() << "use: set_log "; + fail_msg_writer() << tr("use: set_log "); return true; } uint16_t l = 0; if(!epee::string_tools::get_xtype_from_string(l, args[0])) { - fail_msg_writer() << "wrong number format, use: set_log "; + fail_msg_writer() << tr("wrong number format, use: set_log "); return true; } if(LOG_LEVEL_4 < l) { - fail_msg_writer() << "wrong number range, use: set_log "; + fail_msg_writer() << tr("wrong number range, use: set_log "); return true; } @@ -378,13 +381,13 @@ bool simple_wallet::ask_wallet_create_if_needed() bool valid_path = false; do { wallet_path = command_line::input_line( - "Specify wallet file name (e.g., wallet.bin). If the wallet doesn't exist, it will be created.\n" - "Wallet file name: " + tr("Specify wallet file name (e.g., wallet.bin). If the wallet doesn't exist, it will be created.\n" + "Wallet file name: ") ); valid_path = tools::wallet2::wallet_valid_path_format(wallet_path); if (!valid_path) { - fail_msg_writer() << "wallet file path not valid: " << wallet_path; + fail_msg_writer() << tr("wallet file path not valid: ") << wallet_path; } } while (!valid_path); @@ -403,7 +406,7 @@ bool simple_wallet::ask_wallet_create_if_needed() { if (!m_generate_new.empty() || m_restore_deterministic_wallet || !m_generate_from_view_key.empty()) { - fail_msg_writer() << "Attempting to generate or restore wallet, but specified file(s) exist. Exiting to not risk overwriting."; + fail_msg_writer() << tr("Attempting to generate or restore wallet, but specified file(s) exist. Exiting to not risk overwriting."); return false; } } @@ -417,12 +420,12 @@ bool simple_wallet::ask_wallet_create_if_needed() { if(!wallet_file_exists) { - std::cout << "The wallet doesn't exist, generating new one" << std::endl; + std::cout << tr("The wallet doesn't exist, generating new one") << std::endl; m_generate_new = wallet_path; r = true; }else { - fail_msg_writer() << "failed to open wallet \"" << wallet_path << "\". Keys file wasn't found"; + fail_msg_writer() << tr("Keys file wasn't found: failed to open wallet: ") << "\"" << wallet_path << "\"."; r = false; } } @@ -436,9 +439,9 @@ bool simple_wallet::ask_wallet_create_if_needed() */ void simple_wallet::print_seed(std::string seed) { - success_msg_writer(true) << "\nPLEASE NOTE: the following 25 words can be used to recover access to your wallet. " << - "Please write them down and store them somewhere safe and secure. Please do not store them in " << - "your email or on file storage services outside of your immediate control.\n"; + success_msg_writer(true) << "\n" << tr("PLEASE NOTE: the following 25 words can be used to recover access to your wallet. " + "Please write them down and store them somewhere safe and secure. Please do not store them in " + "your email or on file storage services outside of your immediate control.\n"); boost::replace_nth(seed, " ", 15, "\n"); boost::replace_nth(seed, " ", 7, "\n"); // don't log @@ -452,13 +455,13 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm) if (!m_daemon_address.empty() && !m_daemon_host.empty() && 0 != m_daemon_port) { - fail_msg_writer() << "you can't specify daemon host or port several times"; + fail_msg_writer() << tr("you can't specify daemon host or port several times"); return false; } if((!m_generate_new.empty()) + (!m_wallet_file.empty()) + (!m_generate_from_view_key.empty()) > 1) { - fail_msg_writer() << "Specifying more than one of --generate-new-wallet=\"wallet_name\", --wallet-file=\"wallet_name\" and --generate-from-keys doesn't make sense!"; + fail_msg_writer() << tr("Specifying more than one of --generate-new-wallet=\"wallet_name\", --wallet-file=\"wallet_name\" and --generate-from-keys doesn't make sense!"); return false; } else if (m_generate_new.empty() && m_wallet_file.empty() && m_generate_from_view_key.empty()) @@ -489,7 +492,7 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm) bool r = pwd_container.read_password(); if (!r) { - fail_msg_writer() << "failed to read wallet password"; + fail_msg_writer() << tr("failed to read wallet password"); return false; } } @@ -504,7 +507,7 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm) { if (m_non_deterministic) { - fail_msg_writer() << "Cannot specify both --restore-deterministic-wallet and --non-deterministic"; + fail_msg_writer() << tr("Cannot specify both --restore-deterministic-wallet and --non-deterministic"); return false; } @@ -513,14 +516,14 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm) m_electrum_seed = command_line::input_line("Specify electrum seed: "); if (m_electrum_seed.empty()) { - fail_msg_writer() << "specify a recovery parameter with the --electrum-seed=\"words list here\""; + fail_msg_writer() << tr("specify a recovery parameter with the --electrum-seed=\"words list here\""); return false; } } if (!crypto::ElectrumWords::words_to_bytes(m_electrum_seed, m_recovery_key, old_language)) { - fail_msg_writer() << "electrum-style word list failed verification"; + fail_msg_writer() << tr("electrum-style word list failed verification"); return false; } } @@ -531,7 +534,7 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm) boost::split(parts,m_generate_from_view_key, boost::is_any_of(":")); if (parts.size() < 3) { - fail_msg_writer() << "--generate-from-view-key needs a address:viewkey:filename triple"; + fail_msg_writer() << tr("--generate-from-view-key needs a address:viewkey:filename triple"); return false; } @@ -541,7 +544,7 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm) crypto::hash new_payment_id; if(!get_account_integrated_address_from_str(address, has_payment_id, new_payment_id, testnet, parts[0])) { - fail_msg_writer() << "Failed to parse address"; + fail_msg_writer() << tr("Failed to parse address"); return false; } @@ -549,7 +552,7 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm) cryptonote::blobdata viewkey_data; if(!epee::string_tools::parse_hexstr_to_binbuff(parts[1], viewkey_data)) { - fail_msg_writer() << "Failed to parse view key secret key"; + fail_msg_writer() << tr("Failed to parse view key secret key"); return false; } crypto::secret_key viewkey = *reinterpret_cast(viewkey_data.data()); @@ -603,9 +606,9 @@ bool simple_wallet::try_connect_to_daemon() { if (!m_wallet->check_connection()) { - fail_msg_writer() << "wallet failed to connect to daemon (" << m_daemon_address << "). " << - "Daemon either is not started or passed wrong port. " << - "Please, make sure that daemon is running or restart the wallet with correct daemon address."; + fail_msg_writer() << tr("wallet failed to connect to daemon: ") << m_daemon_address << ". " << + tr("Daemon either is not started or passed wrong port. " + "Please, make sure that daemon is running or restart the wallet with correct daemon address."); return false; } return true; @@ -624,7 +627,7 @@ std::string simple_wallet::get_mnemonic_language() std::string language_choice; int language_number = -1; crypto::ElectrumWords::get_language_list(language_list); - std::cout << "List of available languages for your wallet's seed:" << std::endl; + std::cout << tr("List of available languages for your wallet's seed:") << std::endl; int ii; std::vector::iterator it; for (it = language_list.begin(), ii = 0; it != language_list.end(); it++, ii++) @@ -633,19 +636,19 @@ std::string simple_wallet::get_mnemonic_language() } while (language_number < 0) { - language_choice = command_line::input_line("Enter the number corresponding to the language of your choice: "); + language_choice = command_line::input_line(tr("Enter the number corresponding to the language of your choice: ")); try { language_number = std::stoi(language_choice); if (!((language_number >= 0) && (static_cast(language_number) < language_list.size()))) { language_number = -1; - fail_msg_writer() << "Invalid language choice passed. Please try again.\n"; + fail_msg_writer() << tr("Invalid language choice passed. Please try again.\n"); } } catch (std::exception &e) { - fail_msg_writer() << "Invalid language choice passed. Please try again.\n"; + fail_msg_writer() << tr("Invalid language choice passed. Please try again.\n"); } } return language_list[language_number]; @@ -668,8 +671,8 @@ bool simple_wallet::new_wallet(const std::string &wallet_file, const std::string if (was_deprecated_wallet) { // The user had used an older version of the wallet with old style mnemonics. - message_writer(epee::log_space::console_color_green, false) << "\nYou had been using " << - "a deprecated version of the wallet. Please use the new seed that we provide.\n"; + message_writer(epee::log_space::console_color_green, false) << "\n" << tr("You had been using " + "a deprecated version of the wallet. Please use the new seed that we provide.\n"); } mnemonic_language = get_mnemonic_language(); } @@ -684,13 +687,13 @@ bool simple_wallet::new_wallet(const std::string &wallet_file, const std::string try { recovery_val = m_wallet->generate(wallet_file, password, recovery_key, recover, two_random); - message_writer(epee::log_space::console_color_white, true) << "Generated new wallet: " + message_writer(epee::log_space::console_color_white, true) << tr("Generated new wallet: ") << m_wallet->get_account().get_public_address_str(m_wallet->testnet()); - std::cout << "view key: " << string_tools::pod_to_hex(m_wallet->get_account().get_keys().m_view_secret_key) << ENDL; + std::cout << tr("view key: ") << string_tools::pod_to_hex(m_wallet->get_account().get_keys().m_view_secret_key) << ENDL; } catch (const std::exception& e) { - fail_msg_writer() << "failed to generate new wallet: " << e.what(); + fail_msg_writer() << tr("failed to generate new wallet: ") << e.what(); return false; } @@ -703,12 +706,12 @@ bool simple_wallet::new_wallet(const std::string &wallet_file, const std::string success_msg_writer() << "**********************************************************************\n" << - "Your wallet has been generated.\n" << - "To start synchronizing with the daemon use \"refresh\" command.\n" << - "Use \"help\" command to see the list of available commands.\n" << - "Always use \"exit\" command when closing simplewallet to save\n" << - "current session's state. Otherwise, you will possibly need to synchronize \n" << - "your wallet again. Your wallet key is NOT under risk anyway.\n" + tr("Your wallet has been generated.\n" + "To start synchronizing with the daemon use \"refresh\" command.\n" + "Use \"help\" command to see the list of available commands.\n" + "Always use \"exit\" command when closing simplewallet to save\n" + "current session's state. Otherwise, you will possibly need to synchronize \n" + "your wallet again. Your wallet key is NOT under risk anyway.\n") ; if (!two_random) @@ -731,13 +734,13 @@ bool simple_wallet::new_wallet(const std::string &wallet_file, const std::string try { m_wallet->generate(wallet_file, password, address, viewkey); - message_writer(epee::log_space::console_color_white, true) << "Generated new watch-only wallet: " + message_writer(epee::log_space::console_color_white, true) << tr("Generated new watch-only wallet: ") << m_wallet->get_account().get_public_address_str(m_wallet->testnet()); - std::cout << "view key: " << string_tools::pod_to_hex(m_wallet->get_account().get_keys().m_view_secret_key) << ENDL; + std::cout << tr("view key: ") << string_tools::pod_to_hex(m_wallet->get_account().get_keys().m_view_secret_key) << ENDL; } catch (const std::exception& e) { - fail_msg_writer() << "failed to generate new wallet: " << e.what(); + fail_msg_writer() << tr("failed to generate new wallet: ") << e.what(); return false; } @@ -750,7 +753,7 @@ bool simple_wallet::open_wallet(const string &wallet_file, const std::string& pa { if (!tools::wallet2::wallet_valid_path_format(wallet_file)) { - fail_msg_writer() << "wallet file path not valid: " << wallet_file; + fail_msg_writer() << tr("wallet file path not valid: ") << wallet_file; return false; } @@ -761,8 +764,8 @@ bool simple_wallet::open_wallet(const string &wallet_file, const std::string& pa try { m_wallet->load(m_wallet_file, password); - std::string wallet_type = m_wallet->watch_only() ? "watch-only wallet" : "wallet"; - message_writer(epee::log_space::console_color_white, true) << "Opened " << wallet_type << ": " + message_writer(epee::log_space::console_color_white, true) << + (m_wallet->watch_only() ? tr("Opened watch-only wallet") : tr("Opened wallet")) << ": " << m_wallet->get_account().get_public_address_str(m_wallet->testnet()); // If the wallet file is deprecated, we should ask for mnemonic language again and store // everything in the new format. @@ -771,8 +774,8 @@ bool simple_wallet::open_wallet(const string &wallet_file, const std::string& pa { if (m_wallet->is_deterministic()) { - message_writer(epee::log_space::console_color_green, false) << "\nYou had been using " << - "a deprecated version of the wallet. Please proceed to upgrade your wallet.\n"; + message_writer(epee::log_space::console_color_green, false) << "\n" << tr("You had been using " + "a deprecated version of the wallet. Please proceed to upgrade your wallet.\n"); std::string mnemonic_language = get_mnemonic_language(); m_wallet->set_seed_language(mnemonic_language); m_wallet->rewrite(m_wallet_file, password); @@ -784,15 +787,15 @@ bool simple_wallet::open_wallet(const string &wallet_file, const std::string& pa } else { - message_writer(epee::log_space::console_color_green, false) << "\nYou had been using " << - "a deprecated version of the wallet. Your wallet file format is being upgraded now.\n"; + message_writer(epee::log_space::console_color_green, false) << "\n" << tr("You had been using " + "a deprecated version of the wallet. Your wallet file format is being upgraded now.\n"); m_wallet->rewrite(m_wallet_file, password); } } } catch (const std::exception& e) { - fail_msg_writer() << "failed to load wallet: " << e.what(); + fail_msg_writer() << tr("failed to load wallet: ") << e.what(); return false; } @@ -801,7 +804,7 @@ bool simple_wallet::open_wallet(const string &wallet_file, const std::string& pa refresh(std::vector()); success_msg_writer() << "**********************************************************************\n" << - "Use \"help\" command to see the list of available commands.\n" << + tr("Use \"help\" command to see the list of available commands.\n") << "**********************************************************************"; return true; } @@ -811,7 +814,7 @@ bool simple_wallet::close_wallet() bool r = m_wallet->deinit(); if (!r) { - fail_msg_writer() << "failed to deinit wallet"; + fail_msg_writer() << tr("failed to deinit wallet"); return false; } @@ -833,7 +836,7 @@ bool simple_wallet::save(const std::vector &args) try { m_wallet->store(); - success_msg_writer() << "Wallet data saved"; + success_msg_writer() << tr("Wallet data saved"); } catch (const std::exception& e) { @@ -848,22 +851,22 @@ bool simple_wallet::save_watch_only(const std::vector &args/* = std bool success = false; tools::password_container pwd_container; - success = pwd_container.read_password("Password for the new watch-only wallet"); + success = pwd_container.read_password(tr("Password for the new watch-only wallet")); if (!success) { - fail_msg_writer() << "failed to read wallet password"; + fail_msg_writer() << tr("failed to read wallet password"); return true; } std::string password = pwd_container.password(); - success = pwd_container.read_password("Enter new password again"); + success = pwd_container.read_password(tr("Enter new password again")); if (!success) { - fail_msg_writer() << "failed to read wallet password"; + fail_msg_writer() << tr("failed to read wallet password"); return true; } if (password != pwd_container.password()) { - fail_msg_writer() << "passwords do not match"; + fail_msg_writer() << tr("passwords do not match"); return true; } @@ -900,8 +903,8 @@ bool simple_wallet::start_mining(const std::vector& args) if (!ok) { - fail_msg_writer() << "invalid arguments. Please use start_mining [], " << - " should be from 1 to " << max_mining_threads_count; + fail_msg_writer() << tr("invalid arguments. Please use start_mining [], " + " should be from 1 to ") << max_mining_threads_count; return true; } @@ -909,9 +912,9 @@ bool simple_wallet::start_mining(const std::vector& args) bool r = net_utils::invoke_http_json_remote_command2(m_daemon_address + "/start_mining", req, res, m_http_client); std::string err = interpret_rpc_response(r, res.status); if (err.empty()) - success_msg_writer() << "Mining started in daemon"; + success_msg_writer() << tr("Mining started in daemon"); else - fail_msg_writer() << "mining has NOT been started: " << err; + fail_msg_writer() << tr("mining has NOT been started: ") << err; return true; } //---------------------------------------------------------------------------------------------------- @@ -925,9 +928,9 @@ bool simple_wallet::stop_mining(const std::vector& args) bool r = net_utils::invoke_http_json_remote_command2(m_daemon_address + "/stop_mining", req, res, m_http_client); std::string err = interpret_rpc_response(r, res.status); if (err.empty()) - success_msg_writer() << "Mining stopped in daemon"; + success_msg_writer() << tr("Mining stopped in daemon"); else - fail_msg_writer() << "mining has NOT been stopped: " << err; + fail_msg_writer() << tr("mining has NOT been stopped: ") << err; return true; } //---------------------------------------------------------------------------------------------------- @@ -941,9 +944,9 @@ bool simple_wallet::save_bc(const std::vector& args) bool r = net_utils::invoke_http_json_remote_command2(m_daemon_address + "/save_bc", req, res, m_http_client); std::string err = interpret_rpc_response(r, res.status); if (err.empty()) - success_msg_writer() << "Blockchain saved"; + success_msg_writer() << tr("Blockchain saved"); else - fail_msg_writer() << "Blockchain can't be saved: " << err; + fail_msg_writer() << tr("Blockchain can't be saved: ") << err; return true; } //---------------------------------------------------------------------------------------------------- @@ -955,27 +958,27 @@ void simple_wallet::on_new_block(uint64_t height, const cryptonote::block& block void simple_wallet::on_money_received(uint64_t height, const cryptonote::transaction& tx, size_t out_index) { message_writer(epee::log_space::console_color_green, false) << - "Height " << height << - ", transaction " << get_transaction_hash(tx) << - ", received " << print_money(tx.vout[out_index].amount); + tr("Height ") << height << ", " << + tr("transaction ") << get_transaction_hash(tx) << ", " << + tr("received ") << print_money(tx.vout[out_index].amount); m_refresh_progress_reporter.update(height, true); } //---------------------------------------------------------------------------------------------------- void simple_wallet::on_money_spent(uint64_t height, const cryptonote::transaction& in_tx, size_t out_index, const cryptonote::transaction& spend_tx) { message_writer(epee::log_space::console_color_magenta, false) << - "Height " << height << - ", transaction " << get_transaction_hash(spend_tx) << - ", spent " << print_money(in_tx.vout[out_index].amount); + tr("Height ") << height << ", " << + tr("transaction ") << get_transaction_hash(spend_tx) << ", " << + tr("spent ") << print_money(in_tx.vout[out_index].amount); m_refresh_progress_reporter.update(height, true); } //---------------------------------------------------------------------------------------------------- void simple_wallet::on_skip_transaction(uint64_t height, const cryptonote::transaction& tx) { message_writer(epee::log_space::console_color_red, true) << - "Height " << height << - ", transaction " << get_transaction_hash(tx) << - ", unsupported transaction format"; + tr("Height ") << height << ", " << + tr("transaction ") << get_transaction_hash(tx) << ", " << + tr("unsupported transaction format"); m_refresh_progress_reporter.update(height, true); } //---------------------------------------------------------------------------------------------------- @@ -984,7 +987,7 @@ bool simple_wallet::refresh(const std::vector& args) if (!try_connect_to_daemon()) return true; - message_writer() << "Starting refresh..."; + message_writer() << tr("Starting refresh..."); size_t fetched_blocks = 0; size_t start_height = 0; @@ -1007,46 +1010,46 @@ bool simple_wallet::refresh(const std::vector& args) ok = true; // Clear line "Height xxx of xxx" std::cout << "\r \r"; - success_msg_writer(true) << "Refresh done, blocks received: " << fetched_blocks; + success_msg_writer(true) << tr("Refresh done, blocks received: ") << fetched_blocks; show_balance(); } catch (const tools::error::daemon_busy&) { - ss << "daemon is busy. Please try later"; + ss << tr("daemon is busy. Please try later"); } catch (const tools::error::no_connection_to_daemon&) { - ss << "no connection to daemon. Please, make sure daemon is running"; + ss << tr("no connection to daemon. Please, make sure daemon is running"); } catch (const tools::error::wallet_rpc_error& e) { LOG_ERROR("Unknown RPC error: " << e.to_string()); - ss << "RPC error \"" << e.what() << '"'; + ss << tr("RPC error: ") << e.what(); } catch (const tools::error::refresh_error& e) { LOG_ERROR("refresh error: " << e.to_string()); - ss << e.what(); + ss << tr("Error refreshing: ") << e.what(); } catch (const tools::error::wallet_internal_error& e) { LOG_ERROR("internal error: " << e.to_string()); - ss << "internal error: " << e.what(); + ss << tr("internal error: ") << e.what(); } catch (const std::exception& e) { LOG_ERROR("unexpected error: " << e.what()); - ss << "unexpected error: " << e.what(); + ss << tr("unexpected error: ") << e.what(); } catch (...) { LOG_ERROR("Unknown error"); - ss << "unknown error"; + ss << tr("unknown error"); } if (!ok) { - fail_msg_writer() << "refresh failed: " << ss.str() << ". Blocks received: " << fetched_blocks; + fail_msg_writer() << tr("refresh failed: ") << ss.str() << ". " << tr("Blocks received: ") << fetched_blocks; } return true; @@ -1054,8 +1057,9 @@ bool simple_wallet::refresh(const std::vector& args) //---------------------------------------------------------------------------------------------------- bool simple_wallet::show_balance(const std::vector& args/* = std::vector()*/) { - success_msg_writer() << "balance: " << print_money(m_wallet->balance()) << ", unlocked balance: " << print_money(m_wallet->unlocked_balance()) - << ", including unlocked dust: " << print_money(m_wallet->unlocked_dust_balance(tools::tx_dust_policy(::config::DEFAULT_DUST_THRESHOLD))); + success_msg_writer() << tr("balance: ") << print_money(m_wallet->balance()) << ", " + << tr("unlocked balance: ") << print_money(m_wallet->unlocked_balance()) << ", " + << tr("including unlocked dust: ") << print_money(m_wallet->unlocked_dust_balance(tools::tx_dust_policy(::config::DEFAULT_DUST_THRESHOLD))); return true; } //---------------------------------------------------------------------------------------------------- @@ -1087,14 +1091,15 @@ bool simple_wallet::show_incoming_transfers(const std::vector& args { if (!transfers_found) { - message_writer() << " amount \tspent\tglobal index\t tx id"; + message_writer() << boost::format("%21s%8s%16s%68s") % tr("amount") % tr("spent") % tr("global index") % tr("tx id"); transfers_found = true; } message_writer(td.m_spent ? epee::log_space::console_color_magenta : epee::log_space::console_color_green, false) << - std::setw(21) << print_money(td.amount()) << '\t' << - std::setw(3) << (td.m_spent ? 'T' : 'F') << " \t" << - std::setw(12) << td.m_global_output_index << '\t' << - get_transaction_hash(td.m_tx); + boost::format("%21s%8s%16u%68s") % + print_money(td.amount()) % + (td.m_spent ? "T" : "F") % + td.m_global_output_index % + get_transaction_hash (td.m_tx); } } @@ -1102,15 +1107,15 @@ bool simple_wallet::show_incoming_transfers(const std::vector& args { if (!filter) { - success_msg_writer() << "No incoming transfers"; + success_msg_writer() << tr("No incoming transfers"); } else if (available) { - success_msg_writer() << "No incoming available transfers"; + success_msg_writer() << tr("No incoming available transfers"); } else { - success_msg_writer() << "No incoming unavailable transfers"; + success_msg_writer() << tr("No incoming unavailable transfers"); } } @@ -1121,13 +1126,12 @@ bool simple_wallet::show_payments(const std::vector &args) { if(args.empty()) { - fail_msg_writer() << "expected at least one payment_id"; + fail_msg_writer() << tr("expected at least one payment_id"); return true; } - message_writer() << " payment \t" << - " transaction \t" << - " height\t amount \tunlock time"; + message_writer() << boost::format("%68s%68s%12s%21s%16s") % + tr("payment") % tr("transaction") % tr("height") % tr("amount") % tr("unlock time"); bool payments_found = false; for(std::string arg : args) @@ -1139,7 +1143,7 @@ bool simple_wallet::show_payments(const std::vector &args) m_wallet->get_payments(payment_id, payments); if(payments.empty()) { - success_msg_writer() << "No payments with id " << payment_id; + success_msg_writer() << tr("No payments with id ") << payment_id; continue; } @@ -1150,16 +1154,17 @@ bool simple_wallet::show_payments(const std::vector &args) payments_found = true; } success_msg_writer(true) << - payment_id << '\t' << - pd.m_tx_hash << '\t' << - std::setw(8) << pd.m_block_height << '\t' << - std::setw(21) << print_money(pd.m_amount) << '\t' << + boost::format("%68s%68s%12s%21s%16s") % + payment_id % + pd.m_tx_hash % + pd.m_block_height % + print_money(pd.m_amount) % pd.m_unlock_time; } } else { - fail_msg_writer() << "payment id has invalid format: \"" << arg << "\", expected 64-character string"; + fail_msg_writer() << tr("payment id has invalid format, expected 64-character string: ") << arg; } } @@ -1185,7 +1190,7 @@ bool simple_wallet::show_blockchain_height(const std::vector& args) if (err.empty()) success_msg_writer() << bc_height; else - fail_msg_writer() << "failed to get blockchain height: " << err; + fail_msg_writer() << tr("failed to get blockchain height: ") << err; return true; } @@ -1211,13 +1216,13 @@ bool simple_wallet::transfer(const std::vector &args_) if(local_args.size() < 2) { - fail_msg_writer() << "wrong number of arguments"; + fail_msg_writer() << tr("wrong number of arguments"); return true; } if(m_wallet->watch_only()) { - fail_msg_writer() << "This is a watch only wallet"; + fail_msg_writer() << tr("This is a watch only wallet"); return true; } @@ -1239,7 +1244,7 @@ bool simple_wallet::transfer(const std::vector &args_) if(!r) { - fail_msg_writer() << "payment id has invalid format: \"" << payment_id_str << "\", expected 64-character string"; + fail_msg_writer() << tr("payment id has invalid format, expected 64-character string: ") << payment_id_str; return true; } payment_id_seen = true; @@ -1272,48 +1277,49 @@ bool simple_wallet::transfer(const std::vector &args_) std::string dnssec_str; if (dnssec_ok) { - dnssec_str = "DNSSEC validation passed"; + dnssec_str = tr("DNSSEC validation passed"); } else { - dnssec_str = "WARNING: DNSSEC validation was unsuccessful, this address may not be correct!"; + dnssec_str = tr("WARNING: DNSSEC validation was unsuccessful, this address may not be correct!"); } std::stringstream prompt; - prompt << "For URL: " << url + prompt << tr("For URL: ") << url << ", " << dnssec_str << std::endl - << " Monero Address = " << addresses_from_dns[0] + << tr(" Monero Address = ") << addresses_from_dns[0] << std::endl - << "Is this OK? (Y/n) " + << tr("Is this OK? (Y/n) ") ; // prompt the user for confirmation given the dns query and dnssec status std::string confirm_dns_ok = command_line::input_line(prompt.str()); - if (confirm_dns_ok != "Y" && confirm_dns_ok != "y" && confirm_dns_ok != "Yes" && confirm_dns_ok != "yes") + if (confirm_dns_ok != "Y" && confirm_dns_ok != "y" && confirm_dns_ok != "Yes" && confirm_dns_ok != "yes" + && confirm_dns_ok != tr("yes") && confirm_dns_ok != tr("no")) { - fail_msg_writer() << "You have cancelled the transfer request"; + fail_msg_writer() << tr("You have cancelled the transfer request"); return true; } } else { - fail_msg_writer() << "Failed to get a Monero address from: " << local_args[i]; + fail_msg_writer() << tr("Failed to get a Monero address from: ") << local_args[i]; return true; } } else if (addresses_from_dns.size() > 1) { - fail_msg_writer() << "Multiple Monero addresses found for given URL: " << url << ", this is not yet supported."; + fail_msg_writer() << tr("Not yet supported: Multiple Monero addresses found for given URL: ") << url; } else { - fail_msg_writer() << "Wrong address: " << local_args[i]; + fail_msg_writer() << tr("Wrong address: ") << local_args[i]; return true; } } if (has_payment_id) { if (payment_id_seen && payment_id != new_payment_id) { - fail_msg_writer() << "A single transaction cannot use more than one payment id: " << local_args[i]; + fail_msg_writer() << tr("A single transaction cannot use more than one payment id: ") << local_args[i]; return true; } @@ -1324,7 +1330,7 @@ bool simple_wallet::transfer(const std::vector &args_) bool r = add_extra_nonce_to_tx_extra(extra, extra_nonce); if(!r) { - fail_msg_writer() << "Failed to set up payment id, though it was decoded correctly"; + fail_msg_writer() << tr("Failed to set up payment id, though it was decoded correctly"); return true; } payment_id = new_payment_id; @@ -1334,8 +1340,8 @@ bool simple_wallet::transfer(const std::vector &args_) bool ok = cryptonote::parse_amount(de.amount, local_args[i + 1]); if(!ok || 0 == de.amount) { - fail_msg_writer() << "amount is wrong: " << local_args[i] << ' ' << local_args[i + 1] << - ", expected number from 0 to " << print_money(std::numeric_limits::max()); + fail_msg_writer() << tr("amount is wrong: ") << local_args[i] << ' ' << local_args[i + 1] << + ", " << tr("expected number from 0 to ") << print_money(std::numeric_limits::max()); return true; } @@ -1350,14 +1356,13 @@ bool simple_wallet::transfer(const std::vector &args_) // if more than one tx necessary, prompt user to confirm if (ptx_vector.size() > 1) { - std::string prompt_str = "Your transaction needs to be split into "; - prompt_str += std::to_string(ptx_vector.size()); - prompt_str += " transactions. This will result in a transaction fee being applied to each transaction"; - prompt_str += ". Is this okay? (Y/Yes/N/No)"; + std::string prompt_str = (boost::format(tr("Your transaction needs to be split into %zu transactions. " + "This will result in a transaction fee being applied to each transaction. Is this okay? (Y/Yes/N/No)")) % + ptx_vector.size()).str(); std::string accepted = command_line::input_line(prompt_str); if (accepted != "Y" && accepted != "y" && accepted != "Yes" && accepted != "yes") { - fail_msg_writer() << "Transaction cancelled."; + fail_msg_writer() << tr("Transaction cancelled."); // would like to return false, because no tx made, but everything else returns true // and I don't know what returning false might adversely affect. *sigh* @@ -1370,7 +1375,7 @@ bool simple_wallet::transfer(const std::vector &args_) { auto & ptx = ptx_vector.back(); m_wallet->commit_tx(ptx); - success_msg_writer(true) << "Money successfully sent, transaction " << get_transaction_hash(ptx.tx); + success_msg_writer(true) << tr("Money successfully sent, transaction ") << get_transaction_hash(ptx.tx); // if no exception, remove element from vector ptx_vector.pop_back(); @@ -1378,43 +1383,45 @@ bool simple_wallet::transfer(const std::vector &args_) } catch (const tools::error::daemon_busy&) { - fail_msg_writer() << "daemon is busy. Please try later"; + fail_msg_writer() << tr("daemon is busy. Please try later"); } catch (const tools::error::no_connection_to_daemon&) { - fail_msg_writer() << "no connection to daemon. Please, make sure daemon is running."; + fail_msg_writer() << tr("no connection to daemon. Please, make sure daemon is running."); } catch (const tools::error::wallet_rpc_error& e) { LOG_ERROR("Unknown RPC error: " << e.to_string()); - fail_msg_writer() << "RPC error \"" << e.what() << '"'; + fail_msg_writer() << tr("RPC error: ") << e.what(); } catch (const tools::error::get_random_outs_error&) { - fail_msg_writer() << "failed to get random outputs to mix"; + fail_msg_writer() << tr("failed to get random outputs to mix"); } catch (const tools::error::not_enough_money& e) { - fail_msg_writer() << "not enough money to transfer, available only " << print_money(e.available()) << - ", transaction amount " << print_money(e.tx_amount() + e.fee()) << " = " << print_money(e.tx_amount()) << - " + " << print_money(e.fee()) << " (fee)"; + fail_msg_writer() << boost::format(tr("not enough money to transfer, available only %s, transaction amount %s = %s + %s (fee)")) % + print_money(e.available()) % + print_money(e.tx_amount() + e.fee()) % + print_money(e.tx_amount()) % + print_money(e.fee()); } catch (const tools::error::not_enough_outs_to_mix& e) { auto writer = fail_msg_writer(); - writer << "not enough outputs for specified mixin_count = " << e.mixin_count() << ":"; + writer << tr("not enough outputs for specified mixin_count") << " = " << e.mixin_count() << ":"; for (const cryptonote::COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::outs_for_amount& outs_for_amount : e.scanty_outs()) { - writer << "\noutput amount = " << print_money(outs_for_amount.amount) << ", fount outputs to mix = " << outs_for_amount.outs.size(); + writer << "\n" << tr("output amount") << " = " << print_money(outs_for_amount.amount) << ", " << tr("found outputs to mix") << " = " << outs_for_amount.outs.size(); } } catch (const tools::error::tx_not_constructed&) { - fail_msg_writer() << "transaction was not constructed"; + fail_msg_writer() << tr("transaction was not constructed"); } catch (const tools::error::tx_rejected& e) { - fail_msg_writer() << "transaction " << get_transaction_hash(e.tx()) << " was rejected by daemon with status \"" << e.status() << '"'; + fail_msg_writer() << (boost::format(tr("transaction %s was rejected by daemon with status: ")) % get_transaction_hash(e.tx())) << e.status(); } catch (const tools::error::tx_sum_overflow& e) { @@ -1422,31 +1429,31 @@ bool simple_wallet::transfer(const std::vector &args_) } catch (const tools::error::zero_destination&) { - fail_msg_writer() << "one of destinations is zero"; + fail_msg_writer() << tr("one of destinations is zero"); } catch (const tools::error::tx_too_big& e) { - fail_msg_writer() << "Failed to find a suitable way to split transactions"; + fail_msg_writer() << tr("Failed to find a suitable way to split transactions"); } catch (const tools::error::transfer_error& e) { LOG_ERROR("unknown transfer error: " << e.to_string()); - fail_msg_writer() << "unknown transfer error: " << e.what(); + fail_msg_writer() << tr("unknown transfer error: ") << e.what(); } catch (const tools::error::wallet_internal_error& e) { LOG_ERROR("internal error: " << e.to_string()); - fail_msg_writer() << "internal error: " << e.what(); + fail_msg_writer() << tr("internal error: ") << e.what(); } catch (const std::exception& e) { LOG_ERROR("unexpected error: " << e.what()); - fail_msg_writer() << "unexpected error: " << e.what(); + fail_msg_writer() << tr("unexpected error: ") << e.what(); } catch (...) { LOG_ERROR("Unknown error"); - fail_msg_writer() << "unknown error"; + fail_msg_writer() << tr("unknown error"); } return true; @@ -1460,7 +1467,7 @@ bool simple_wallet::sweep_dust(const std::vector &args_) if(m_wallet->watch_only()) { - fail_msg_writer() << "This is a watch only wallet"; + fail_msg_writer() << tr("This is a watch only wallet"); return true; } @@ -1478,18 +1485,22 @@ bool simple_wallet::sweep_dust(const std::vector &args_) total_fee += ptx_vector[n].fee; } - std::string prompt_str = "Sweeping " + print_money(total_dust); + std::string prompt_str = tr("Sweeping ") + print_money(total_dust); if (ptx_vector.size() > 1) { - prompt_str += " in "; - prompt_str += std::to_string(ptx_vector.size()); - prompt_str += " transactions"; + prompt_str = (boost::format(tr("Sweeping %s in %zu transactions for a total fee of %s. Is this okay? (Y/Yes/N/No)")) % + print_money(total_dust) % + ptx_vector.size() % + print_money(total_fee)).str(); + } + else { + prompt_str = (boost::format(tr("Sweeping %s for a total fee of %s. Is this okay? (Y/Yes/N/No)")) % + print_money(total_dust) % + print_money(total_fee)).str(); } - prompt_str += " for a total fee of " + print_money(total_fee); - prompt_str += ". Is this okay? (Y/Yes/N/No)"; std::string accepted = command_line::input_line(prompt_str); if (accepted != "Y" && accepted != "y" && accepted != "Yes" && accepted != "yes") { - fail_msg_writer() << "Transaction cancelled."; + fail_msg_writer() << tr("Transaction cancelled."); // would like to return false, because no tx made, but everything else returns true // and I don't know what returning false might adversely affect. *sigh* @@ -1501,7 +1512,7 @@ bool simple_wallet::sweep_dust(const std::vector &args_) { auto & ptx = ptx_vector.back(); m_wallet->commit_tx(ptx); - success_msg_writer(true) << "Money successfully sent, transaction " << get_transaction_hash(ptx.tx); + success_msg_writer(true) << tr("Money successfully sent, transaction: ") << get_transaction_hash(ptx.tx); // if no exception, remove element from vector ptx_vector.pop_back(); @@ -1509,43 +1520,45 @@ bool simple_wallet::sweep_dust(const std::vector &args_) } catch (const tools::error::daemon_busy&) { - fail_msg_writer() << "daemon is busy. Please try later"; + fail_msg_writer() << tr("daemon is busy. Please try later"); } catch (const tools::error::no_connection_to_daemon&) { - fail_msg_writer() << "no connection to daemon. Please, make sure daemon is running."; + fail_msg_writer() << tr("no connection to daemon. Please, make sure daemon is running."); } catch (const tools::error::wallet_rpc_error& e) { LOG_ERROR("Unknown RPC error: " << e.to_string()); - fail_msg_writer() << "RPC error \"" << e.what() << '"'; + fail_msg_writer() << tr("RPC error: ") << e.what(); } catch (const tools::error::get_random_outs_error&) { - fail_msg_writer() << "failed to get random outputs to mix"; + fail_msg_writer() << tr("failed to get random outputs to mix"); } catch (const tools::error::not_enough_money& e) { - fail_msg_writer() << "not enough money to transfer, available only " << print_money(e.available()) << - ", transaction amount " << print_money(e.tx_amount() + e.fee()) << " = " << print_money(e.tx_amount()) << - " + " << print_money(e.fee()) << " (fee)"; + fail_msg_writer() << boost::format(tr("not enough money to transfer, available only %s, transaction amount %s = %s + %s (fee)")) % + print_money(e.available()) % + print_money(e.tx_amount() + e.fee()) % + print_money(e.tx_amount()) % + print_money(e.fee()); } catch (const tools::error::not_enough_outs_to_mix& e) { auto writer = fail_msg_writer(); - writer << "not enough outputs for specified mixin_count = " << e.mixin_count() << ":"; + writer << tr("not enough outputs for specified mixin_count") << " = " << e.mixin_count() << ":"; for (const cryptonote::COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::outs_for_amount& outs_for_amount : e.scanty_outs()) { - writer << "\noutput amount = " << print_money(outs_for_amount.amount) << ", fount outputs to mix = " << outs_for_amount.outs.size(); + writer << "\n" << tr("output amount") << " = " << print_money(outs_for_amount.amount) << ", " << tr("found outputs to mix") << " = " << outs_for_amount.outs.size(); } } catch (const tools::error::tx_not_constructed&) { - fail_msg_writer() << "transaction was not constructed"; + fail_msg_writer() << tr("transaction was not constructed"); } catch (const tools::error::tx_rejected& e) { - fail_msg_writer() << "transaction " << get_transaction_hash(e.tx()) << " was rejected by daemon with status \"" << e.status() << '"'; + fail_msg_writer() << (boost::format(tr("transaction %s was rejected by daemon with status: ")) % get_transaction_hash(e.tx())) << e.status(); } catch (const tools::error::tx_sum_overflow& e) { @@ -1553,31 +1566,31 @@ bool simple_wallet::sweep_dust(const std::vector &args_) } catch (const tools::error::zero_destination&) { - fail_msg_writer() << "one of destinations is zero"; + fail_msg_writer() << tr("one of destinations is zero"); } catch (const tools::error::tx_too_big& e) { - fail_msg_writer() << "Failed to find a suitable way to split transactions"; + fail_msg_writer() << tr("Failed to find a suitable way to split transactions"); } catch (const tools::error::transfer_error& e) { LOG_ERROR("unknown transfer error: " << e.to_string()); - fail_msg_writer() << "unknown transfer error: " << e.what(); + fail_msg_writer() << tr("unknown transfer error: ") << e.what(); } catch (const tools::error::wallet_internal_error& e) { LOG_ERROR("internal error: " << e.to_string()); - fail_msg_writer() << "internal error: " << e.what(); + fail_msg_writer() << tr("internal error: ") << e.what(); } catch (const std::exception& e) { LOG_ERROR("unexpected error: " << e.what()); - fail_msg_writer() << "unexpected error: " << e.what(); + fail_msg_writer() << tr("unexpected error: ") << e.what(); } catch (...) { LOG_ERROR("Unknown error"); - fail_msg_writer() << "unknown error"; + fail_msg_writer() << tr("unknown error"); } return true; @@ -1586,7 +1599,7 @@ bool simple_wallet::sweep_dust(const std::vector &args_) bool simple_wallet::run() { std::string addr_start = m_wallet->get_account().get_public_address_str(m_wallet->testnet()).substr(0, 6); - return m_cmd_binder.run_handling("[wallet " + addr_start + "]: ", ""); + return m_cmd_binder.run_handling(std::string("[") + tr("wallet") + " " + addr_start + "]: ", ""); } //---------------------------------------------------------------------------------------------------- void simple_wallet::stop() @@ -1606,14 +1619,14 @@ bool simple_wallet::print_integrated_address(const std::vector &arg crypto::hash payment_id; if (args.size() > 1) { - fail_msg_writer() << "integrated_address only takes one or zero arguments"; + fail_msg_writer() << tr("integrated_address only takes one or zero arguments"); return true; } if (args.size() == 0) { crypto::generate_random_bytes(32, payment_id.data); - success_msg_writer() << "Random payment ID: " << payment_id; - success_msg_writer() << "Matching integrated address: " << m_wallet->get_account().get_public_integrated_address_str(payment_id, m_wallet->testnet()); + success_msg_writer() << tr("Random payment ID: ") << payment_id; + success_msg_writer() << tr("Matching integrated address: ") << m_wallet->get_account().get_public_integrated_address_str(payment_id, m_wallet->testnet()); return true; } if(tools::wallet2::parse_payment_id(args.back(), payment_id)) @@ -1629,16 +1642,17 @@ bool simple_wallet::print_integrated_address(const std::vector &arg { if (has_payment_id) { - success_msg_writer() << "Integrated address: account " << get_account_address_as_str(m_wallet->testnet(),addr) << ", payment id " << payment_id; + success_msg_writer() << boost::format(tr("Integrated address: account %s, payment id %s")) % + get_account_address_as_str(m_wallet->testnet(),addr) % epee::string_tools::pod_to_hex(payment_id); } else { - success_msg_writer() << "Standard address: account " << get_account_address_as_str(m_wallet->testnet(),addr); + success_msg_writer() << tr("Standard address: account: ") << get_account_address_as_str(m_wallet->testnet(),addr); } return true; } } - fail_msg_writer() << "Failed to parse payment id or address"; + fail_msg_writer() << tr("Failed to parse payment id or address"); return true; } //---------------------------------------------------------------------------------------------------- @@ -1657,11 +1671,11 @@ int main(int argc, char* argv[]) string_tools::set_module_name_and_folder(argv[0]); - po::options_description desc_general("General options"); + po::options_description desc_general(sw::tr("General options")); command_line::add_arg(desc_general, command_line::arg_help); command_line::add_arg(desc_general, command_line::arg_version); - po::options_description desc_params("Wallet options"); + po::options_description desc_params(sw::tr("Wallet options")); command_line::add_arg(desc_params, arg_wallet_file); command_line::add_arg(desc_params, arg_generate_new_wallet); command_line::add_arg(desc_params, arg_generate_from_view_key); @@ -1674,7 +1688,7 @@ int main(int argc, char* argv[]) bf::path default_log {log_space::log_singletone::get_default_log_folder()}; default_log /= log_space::log_singletone::get_default_log_file(); - std::cout << "default_log: " << default_log << ENDL; + std::cout << sw::tr("default_log: ") << default_log << ENDL; command_line::add_arg(desc_params, arg_log_file, default_log.string()); command_line::add_arg(desc_params, arg_restore_deterministic_wallet ); @@ -1687,6 +1701,8 @@ int main(int argc, char* argv[]) po::positional_options_description positional_options; positional_options.add(arg_command.name, -1); + i18n_set_language("translations", "monero"); + po::options_description desc_all; desc_all.add(desc_general).add(desc_params); cryptonote::simple_wallet w; @@ -1697,14 +1713,14 @@ int main(int argc, char* argv[]) if (command_line::get_arg(vm, command_line::arg_help)) { - success_msg_writer() << CRYPTONOTE_NAME << " wallet v" << MONERO_VERSION_FULL; - success_msg_writer() << "Usage: simplewallet [--wallet-file=|--generate-new-wallet=] [--daemon-address=:] []"; + success_msg_writer() << CRYPTONOTE_NAME << " " << sw::tr("wallet") << " v" << MONERO_VERSION_FULL; + success_msg_writer() << sw::tr("Usage:") << " simplewallet [--wallet-file=|--generate-new-wallet=] [--daemon-address=:] []"; success_msg_writer() << desc_all << '\n' << w.get_commands_str(); return false; } else if (command_line::get_arg(vm, command_line::arg_version)) { - success_msg_writer() << CRYPTONOTE_NAME << " wallet v" << MONERO_VERSION_FULL; + success_msg_writer() << CRYPTONOTE_NAME << " " << sw::tr("wallet") << " v" << MONERO_VERSION_FULL; return false; } @@ -1735,12 +1751,13 @@ int main(int argc, char* argv[]) LOG_LEVEL_4 ); - message_writer(epee::log_space::console_color_white, true) << CRYPTONOTE_NAME << " wallet v" << MONERO_VERSION_FULL; + message_writer(epee::log_space::console_color_white, true) << CRYPTONOTE_NAME << " " << sw::tr("wallet") << " v" << MONERO_VERSION_FULL; if(command_line::has_arg(vm, arg_log_level)) log_level = command_line::get_arg(vm, arg_log_level); LOG_PRINT_L0("Setting log level = " << log_level); - message_writer(epee::log_space::console_color_white, true) << "Logging at log level " << log_level << " to " << log_file_path.string(); + message_writer(epee::log_space::console_color_white, true) << boost::format(sw::tr("Logging at log level %d to %s")) % + log_level % log_file_path.string(); log_space::get_set_log_detalisation_level(true, log_level); if(command_line::has_arg(vm, tools::wallet_rpc_server::arg_rpc_bind_port)) @@ -1749,17 +1766,17 @@ int main(int argc, char* argv[]) //runs wallet with rpc interface if(!command_line::has_arg(vm, arg_wallet_file) ) { - LOG_ERROR("Wallet file not set."); + LOG_ERROR(sw::tr("Wallet file not set.")); return 1; } if(!command_line::has_arg(vm, arg_daemon_address) ) { - LOG_ERROR("Daemon address not set."); + LOG_ERROR(sw::tr("Daemon address not set.")); return 1; } if(!command_line::has_arg(vm, arg_password) ) { - LOG_ERROR("Wallet password not set."); + LOG_ERROR(sw::tr("Wallet password not set.")); return 1; } @@ -1780,44 +1797,44 @@ int main(int argc, char* argv[]) tools::wallet2 wal(testnet,restricted); try { - LOG_PRINT_L0("Loading wallet..."); + LOG_PRINT_L0(sw::tr("Loading wallet...")); wal.load(wallet_file, wallet_password); wal.init(daemon_address); wal.refresh(); - LOG_PRINT_GREEN("Loaded ok", LOG_LEVEL_0); + LOG_PRINT_GREEN(sw::tr("Loaded ok"), LOG_LEVEL_0); } catch (const std::exception& e) { - LOG_ERROR("Wallet initialize failed: " << e.what()); + LOG_ERROR(sw::tr("Wallet initialization failed: ") << e.what()); return 1; } tools::wallet_rpc_server wrpc(wal); bool r = wrpc.init(vm); - CHECK_AND_ASSERT_MES(r, 1, "Failed to initialize wallet rpc server"); + CHECK_AND_ASSERT_MES(r, 1, sw::tr("Failed to initialize wallet rpc server")); tools::signal_handler::install([&wrpc, &wal] { wrpc.send_stop_signal(); wal.store(); }); - LOG_PRINT_L0("Starting wallet rpc server"); + LOG_PRINT_L0(sw::tr("Starting wallet rpc server")); wrpc.run(); - LOG_PRINT_L0("Stopped wallet rpc server"); + LOG_PRINT_L0(sw::tr("Stopped wallet rpc server")); try { - LOG_PRINT_L0("Storing wallet..."); + LOG_PRINT_L0(sw::tr("Storing wallet...")); wal.store(); - LOG_PRINT_GREEN("Stored ok", LOG_LEVEL_0); + LOG_PRINT_GREEN(sw::tr("Stored ok"), LOG_LEVEL_0); } catch (const std::exception& e) { - LOG_ERROR("Failed to store wallet: " << e.what()); + LOG_ERROR(sw::tr("Failed to store wallet: ") << e.what()); return 1; } }else { //runs wallet with console interface r = w.init(vm); - CHECK_AND_ASSERT_MES(r, 1, "Failed to initialize wallet"); + CHECK_AND_ASSERT_MES(r, 1, sw::tr("Failed to initialize wallet")); std::vector command = command_line::get_arg(vm, arg_command); if (!command.empty()) diff --git a/src/simplewallet/simplewallet.h b/src/simplewallet/simplewallet.h index 2b8ca0ed..ad1dd015 100644 --- a/src/simplewallet/simplewallet.h +++ b/src/simplewallet/simplewallet.h @@ -57,6 +57,9 @@ namespace cryptonote */ class simple_wallet : public tools::i_wallet2_callback { + public: + static const char *tr(const char *str) { return i18n_translate(str, "cryptonote::simple_wallet"); } + public: typedef std::vector command_type; @@ -165,7 +168,7 @@ namespace cryptonote if (std::chrono::milliseconds(1) < current_time - m_print_time || force) { - std::cout << "Height " << height << " of " << m_blockchain_height << '\r'; + std::cout << QT_TRANSLATE_NOOP("Height ", "cryptonote::simple_wallet") << height << " / " << m_blockchain_height << '\r'; m_print_time = current_time; } } diff --git a/translations/monero.ts b/translations/monero.ts new file mode 100644 index 00000000..da832ff2 --- /dev/null +++ b/translations/monero.ts @@ -0,0 +1,996 @@ + + + + + cryptonote::simple_wallet + + + Commands: + + + + + This wallet is watch-only and cannot have a seed. + + + + + The wallet is non-deterministic. Cannot display seed. + + + + + This wallet is watch-only and doesn't have a seed. + + + + + This wallet is non-deterministic and doesn't have a seed. + + + + + + + + failed to read wallet password + + + + + invalid password + + + + + start_mining [<number_of_threads>] - Start mining in daemon + + + + + Stop mining in daemon + + + + + Save current blockchain data + + + + + Resynchronize transactions and balance + + + + + Show current wallet balance + + + + + incoming_transfers [available|unavailable] - Show incoming transfers - all of them or filter them by availability + + + + + payments <payment_id_1> [<payment_id_2> ... <payment_id_N>] - Show payments <payment_id_1>, ... <payment_id_N> + + + + + Show blockchain height + + + + + transfer [<mixin_count>] <addr_1> <amount_1> [<addr_2> <amount_2> ... <addr_N> <amount_N>] [payment_id] - Transfer <amount_1>,... <amount_N> to <address_1>,... <address_N>, respectively. <mixin_count> is the number of transactions yours is indistinguishable from (from 0 to maximum available) + + + + + Send all dust outputs to the same address with mixin 0 + + + + + set_log <level> - Change current log detalization level, <level> is a number 0-4 + + + + + Show current wallet public address + + + + + Convert a payment ID to an integrated address for the current wallet public address (no arguments use a random payment ID), or display standard addres and payment ID corresponding to an integrated addres + + + + + Save wallet synchronized data + + + + + Save watch only keys file + + + + + Get viewkey + + + + + Get spendkey + + + + + Get deterministic seed + + + + + available options: seed language - Set wallet seed langage + + + + + Show this help + + + + + set: needs an argument. available options: seed + + + + + set seed: needs an argument. available options: language + + + + + set: unrecognized argument(s) + + + + + use: set_log <log_level_number_0-4> + + + + + wrong number format, use: set_log <log_level_number_0-4> + + + + + wrong number range, use: set_log <log_level_number_0-4> + + + + + Specify wallet file name (e.g., wallet.bin). If the wallet doesn't exist, it will be created. +Wallet file name: + + + + + + wallet file path not valid: + + + + + Attempting to generate or restore wallet, but specified file(s) exist. Exiting to not risk overwriting. + + + + + The wallet doesn't exist, generating new one + + + + + Keys file wasn't found: failed to open wallet: + + + + + PLEASE NOTE: the following 25 words can be used to recover access to your wallet. Please write them down and store them somewhere safe and secure. Please do not store them in your email or on file storage services outside of your immediate control. + + + + + + you can't specify daemon host or port several times + + + + + Specifying more than one of --generate-new-wallet="wallet_name", --wallet-file="wallet_name" and --generate-from-keys doesn't make sense! + + + + + Cannot specify both --restore-deterministic-wallet and --non-deterministic + + + + + specify a recovery parameter with the --electrum-seed="words list here" + + + + + electrum-style word list failed verification + + + + + --generate-from-view-key needs a address:viewkey:filename triple + + + + + Failed to parse address + + + + + Failed to parse view key secret key + + + + + wallet failed to connect to daemon: + + + + + Daemon either is not started or passed wrong port. Please, make sure that daemon is running or restart the wallet with correct daemon address. + + + + + List of available languages for your wallet's seed: + + + + + Enter the number corresponding to the language of your choice: + + + + + + Invalid language choice passed. Please try again. + + + + + + You had been using a deprecated version of the wallet. Please use the new seed that we provide. + + + + + + Generated new wallet: + + + + + + view key: + + + + + + failed to generate new wallet: + + + + + Your wallet has been generated. +To start synchronizing with the daemon use "refresh" command. +Use "help" command to see the list of available commands. +Always use "exit" command when closing simplewallet to save +current session's state. Otherwise, you will possibly need to synchronize +your wallet again. Your wallet key is NOT under risk anyway. + + + + + + Generated new watch-only wallet: + + + + + Opened watch-only wallet + + + + + Opened wallet + + + + + You had been using a deprecated version of the wallet. Please proceed to upgrade your wallet. + + + + + + You had been using a deprecated version of the wallet. Your wallet file format is being upgraded now. + + + + + + failed to load wallet: + + + + + Use "help" command to see the list of available commands. + + + + + + failed to deinit wallet + + + + + Wallet data saved + + + + + Password for the new watch-only wallet + + + + + Enter new password again + + + + + passwords do not match + + + + + invalid arguments. Please use start_mining [<number_of_threads>], <number_of_threads> should be from 1 to + + + + + Mining started in daemon + + + + + mining has NOT been started: + + + + + Mining stopped in daemon + + + + + mining has NOT been stopped: + + + + + Blockchain saved + + + + + Blockchain can't be saved: + + + + + + + Height + + + + + + + transaction + + + + + received + + + + + spent + + + + + unsupported transaction format + + + + + Starting refresh... + + + + + Refresh done, blocks received: + + + + + + + daemon is busy. Please try later + + + + + no connection to daemon. Please, make sure daemon is running + + + + + + + RPC error: + + + + + Error refreshing: + + + + + + + internal error: + + + + + + + unexpected error: + + + + + + + unknown error + + + + + refresh failed: + + + + + Blocks received: + + + + + balance: + + + + + unlocked balance: + + + + + including unlocked dust: + + + + + + amount + + + + + spent + + + + + global index + + + + + tx id + + + + + No incoming transfers + + + + + No incoming available transfers + + + + + No incoming unavailable transfers + + + + + expected at least one payment_id + + + + + payment + + + + + transaction + + + + + height + + + + + unlock time + + + + + No payments with id + + + + + + payment id has invalid format, expected 64-character string: + + + + + failed to get blockchain height: + + + + + wrong number of arguments + + + + + + This is a watch only wallet + + + + + DNSSEC validation passed + + + + + WARNING: DNSSEC validation was unsuccessful, this address may not be correct! + + + + + For URL: + + + + + Monero Address = + + + + + Is this OK? (Y/n) + + + + + yes + + + + + no + + + + + You have cancelled the transfer request + + + + + Failed to get a Monero address from: + + + + + Not yet supported: Multiple Monero addresses found for given URL: + + + + + Wrong address: + + + + + A single transaction cannot use more than one payment id: + + + + + Failed to set up payment id, though it was decoded correctly + + + + + amount is wrong: + + + + + expected number from 0 to + + + + + Your transaction needs to be split into %zu transactions. This will result in a transaction fee being applied to each transaction. Is this okay? (Y/Yes/N/No) + + + + + + Transaction cancelled. + + + + + Money successfully sent, transaction + + + + + + no connection to daemon. Please, make sure daemon is running. + + + + + + failed to get random outputs to mix + + + + + + not enough money to transfer, available only %s, transaction amount %s = %s + %s (fee) + + + + + + not enough outputs for specified mixin_count + + + + + + output amount + + + + + + found outputs to mix + + + + + + transaction was not constructed + + + + + + transaction %s was rejected by daemon with status: + + + + + + one of destinations is zero + + + + + + Failed to find a suitable way to split transactions + + + + + + unknown transfer error: + + + + + Sweeping + + + + + Sweeping %s in %zu transactions for a total fee of %s. Is this okay? (Y/Yes/N/No) + + + + + Sweeping %s for a total fee of %s. Is this okay? (Y/Yes/N/No) + + + + + Money successfully sent, transaction: + + + + + wallet + + + + + integrated_address only takes one or zero arguments + + + + + Random payment ID: + + + + + Matching integrated address: + + + + + Integrated address: account %s, payment id %s + + + + + Standard address: account: + + + + + Failed to parse payment id or address + + + + + sw + + + Use wallet <arg> + + + + + Generate new wallet and save it to <arg> or <address>.wallet by default + + + + + Generate wallet from (address:viewkey:filename) and save it to <filename> + + + + + Use daemon instance at <host>:<port> + + + + + Use daemon instance at host <arg> instead of localhost + + + + + Wallet password + + + + + Specify electrum seed for wallet recovery/creation + + + + + Recover wallet using electrum-style mnemonic + + + + + creates non-deterministic view and spend keys + + + + + Use daemon instance at port <arg> instead of 8081 + + + + + Specify log file + + + + + Used to deploy test nets. The daemon must be launched with --testnet flag + + + + + Restricts RPC to view only commands + + + + + daemon is busy. Please try later + + + + + possible lost connection to daemon + + + + + Error: + + + + + General options + + + + + Wallet options + + + + + default_log: + + + + + + + wallet + + + + + Usage: + + + + + Logging at log level %d to %s + + + + + Wallet file not set. + + + + + Daemon address not set. + + + + + Wallet password not set. + + + + + Loading wallet... + + + + + Loaded ok + + + + + Wallet initialization failed: + + + + + Failed to initialize wallet rpc server + + + + + Starting wallet rpc server + + + + + Stopped wallet rpc server + + + + + Storing wallet... + + + + + Stored ok + + + + + Failed to store wallet: + + + + + Failed to initialize wallet + + + + diff --git a/utils/translations/build-translations.sh b/utils/translations/build-translations.sh new file mode 100755 index 00000000..0956e633 --- /dev/null +++ b/utils/translations/build-translations.sh @@ -0,0 +1,16 @@ +#!/bin/sh + +lrelease=`which lrelease 2> /dev/null` +if test -z "$lrelease" +then + lrelease=`which lrelease-qt4 2> /dev/null` +fi +if test -z "$lrelease" +then + echo "lrelease not found" + exit 1 +fi + +echo "using $lrelease" +"$lrelease" translations/*.ts + diff --git a/utils/translations/update-translations.sh b/utils/translations/update-translations.sh new file mode 100755 index 00000000..778aa517 --- /dev/null +++ b/utils/translations/update-translations.sh @@ -0,0 +1,16 @@ +#!/bin/sh + +lupdate=`which lupdate 2> /dev/null` +if test -z "$lupdate" +then + lupdate=`which lupdate-qt4 2> /dev/null` +fi +if test -z "$lupdate" +then + echo "lupdate not found" + exit 1 +fi + +echo "using $lupdate" +"$lupdate" `find src -name \*.cpp` -ts translations/*.ts +