refactor: Values pt. 7 - remove tr_formatter_init methods (#6258)

* refactor: initialize libtransmission::Values units in Application::initUnits()

* refactor: use libtransmission::Values instead of Formatter::unitStr()

* refactor: remove Formatter::Size, Formatter:Type

* refactor: use Values::Config to init units in transmission-qt

* refactor: use Values::Config to init units in transmission-mac

* chore: remove unused tr_formatter_foo_init() functions

* chore: make Value::operator+() const

* use Values::Speed, Values::Storage in GTK client

* chore: use snake_case for Formatter methods

* refactor: use Values::Speed in GTK client details dialog

* feat: add Values::Value::is_zero()

* refactor: remove unnecessary UTF8String calls
This commit is contained in:
Charles Kerr 2023-11-15 22:15:40 -06:00 committed by GitHub
parent f8c544397a
commit 76521a1751
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
29 changed files with 321 additions and 400 deletions

View File

@ -487,10 +487,13 @@ void DetailsDialog::Impl::torrent_set_real(tr_quark key, double value)
void DetailsDialog::Impl::options_page_init(Glib::RefPtr<Gtk::Builder> const& /*builder*/) void DetailsDialog::Impl::options_page_init(Glib::RefPtr<Gtk::Builder> const& /*builder*/)
{ {
auto const speed_units_kbyps_str = Speed::units().display_name(Speed::Units::KByps);
honor_limits_check_tag_ = honor_limits_check_->signal_toggled().connect( honor_limits_check_tag_ = honor_limits_check_->signal_toggled().connect(
[this]() { torrent_set_bool(TR_KEY_honorsSessionLimits, honor_limits_check_->get_active()); }); [this]() { torrent_set_bool(TR_KEY_honorsSessionLimits, honor_limits_check_->get_active()); });
down_limited_check_->set_label(fmt::format(down_limited_check_->get_label().raw(), fmt::arg("speed_units", speed_K_str))); down_limited_check_->set_label(
fmt::format(fmt::runtime(down_limited_check_->get_label().raw()), fmt::arg("speed_units", speed_units_kbyps_str)));
down_limited_check_tag_ = down_limited_check_->signal_toggled().connect( down_limited_check_tag_ = down_limited_check_->signal_toggled().connect(
[this]() { torrent_set_bool(TR_KEY_downloadLimited, down_limited_check_->get_active()); }); [this]() { torrent_set_bool(TR_KEY_downloadLimited, down_limited_check_->get_active()); });
@ -498,7 +501,8 @@ void DetailsDialog::Impl::options_page_init(Glib::RefPtr<Gtk::Builder> const& /*
down_limit_spin_tag_ = down_limit_spin_->signal_value_changed().connect( down_limit_spin_tag_ = down_limit_spin_->signal_value_changed().connect(
[this]() { torrent_set_int(TR_KEY_downloadLimit, down_limit_spin_->get_value_as_int()); }); [this]() { torrent_set_int(TR_KEY_downloadLimit, down_limit_spin_->get_value_as_int()); });
up_limited_check_->set_label(fmt::format(up_limited_check_->get_label().raw(), fmt::arg("speed_units", speed_K_str))); up_limited_check_->set_label(
fmt::format(fmt::runtime(up_limited_check_->get_label().raw()), fmt::arg("speed_units", speed_units_kbyps_str)));
up_limited_check_tag_ = up_limited_check_->signal_toggled().connect( up_limited_check_tag_ = up_limited_check_->signal_toggled().connect(
[this]() { torrent_set_bool(TR_KEY_uploadLimited, up_limited_check_->get_active()); }); [this]() { torrent_set_bool(TR_KEY_uploadLimited, up_limited_check_->get_active()); });
@ -1108,14 +1112,14 @@ public:
add(key); add(key);
add(was_updated); add(was_updated);
add(url); add(url);
add(download_rate_double); add(download_rate_speed);
add(download_rate_string); add(download_rate_string);
} }
Gtk::TreeModelColumn<std::string> key; Gtk::TreeModelColumn<std::string> key;
Gtk::TreeModelColumn<bool> was_updated; Gtk::TreeModelColumn<bool> was_updated;
Gtk::TreeModelColumn<Glib::ustring> url; Gtk::TreeModelColumn<Glib::ustring> url;
Gtk::TreeModelColumn<double> download_rate_double; Gtk::TreeModelColumn<Speed> download_rate_speed;
Gtk::TreeModelColumn<Glib::ustring> download_rate_string; Gtk::TreeModelColumn<Glib::ustring> download_rate_string;
}; };
@ -1130,9 +1134,9 @@ public:
add(was_updated); add(was_updated);
add(address); add(address);
add(address_collated); add(address_collated);
add(download_rate_double); add(download_rate_speed);
add(download_rate_string); add(download_rate_string);
add(upload_rate_double); add(upload_rate_speed);
add(upload_rate_string); add(upload_rate_string);
add(client); add(client);
add(progress); add(progress);
@ -1157,9 +1161,9 @@ public:
Gtk::TreeModelColumn<bool> was_updated; Gtk::TreeModelColumn<bool> was_updated;
Gtk::TreeModelColumn<Glib::ustring> address; Gtk::TreeModelColumn<Glib::ustring> address;
Gtk::TreeModelColumn<Glib::ustring> address_collated; Gtk::TreeModelColumn<Glib::ustring> address_collated;
Gtk::TreeModelColumn<double> download_rate_double; Gtk::TreeModelColumn<Speed> download_rate_speed;
Gtk::TreeModelColumn<Glib::ustring> download_rate_string; Gtk::TreeModelColumn<Glib::ustring> download_rate_string;
Gtk::TreeModelColumn<double> upload_rate_double; Gtk::TreeModelColumn<Speed> upload_rate_speed;
Gtk::TreeModelColumn<Glib::ustring> upload_rate_string; Gtk::TreeModelColumn<Glib::ustring> upload_rate_string;
Gtk::TreeModelColumn<Glib::ustring> client; Gtk::TreeModelColumn<Glib::ustring> client;
Gtk::TreeModelColumn<int> progress; Gtk::TreeModelColumn<int> progress;
@ -1219,25 +1223,28 @@ void initPeerRow(
void refreshPeerRow(Gtk::TreeModel::iterator const& iter, tr_peer_stat const* peer) void refreshPeerRow(Gtk::TreeModel::iterator const& iter, tr_peer_stat const* peer)
{ {
std::string up_speed;
std::string down_speed;
std::string up_count;
std::string down_count;
std::string blocks_to_peer;
std::string blocks_to_client;
std::string cancelled_by_peer;
std::string cancelled_by_client;
g_return_if_fail(peer != nullptr); g_return_if_fail(peer != nullptr);
auto const down_speed = Speed{ peer->rateToClient_KBps, Speed::Units::KByps };
auto const up_speed = Speed{ peer->rateToPeer_KBps, Speed::Units::KByps };
auto blocks_to_client = std::string{};
auto blocks_to_peer = std::string{};
auto cancelled_by_client = std::string{};
auto cancelled_by_peer = std::string{};
auto down_count = std::string{};
auto down_speed_string = std::string{};
auto up_count = std::string{};
auto up_speed_string = std::string{};
if (peer->rateToPeer_KBps > 0.01) if (peer->rateToPeer_KBps > 0.01)
{ {
up_speed = Speed{ peer->rateToPeer_KBps, Speed::Units::KByps }.to_string(); up_speed_string = up_speed.to_string();
} }
if (peer->rateToClient_KBps > 0) if (peer->rateToClient_KBps > 0)
{ {
down_speed = Speed{ peer->rateToClient_KBps, Speed::Units::KByps }.to_string(); down_speed_string = down_speed.to_string();
} }
if (peer->activeReqsToPeer > 0) if (peer->activeReqsToPeer > 0)
@ -1275,10 +1282,10 @@ void refreshPeerRow(Gtk::TreeModel::iterator const& iter, tr_peer_stat const* pe
(*iter)[peer_cols.upload_request_count_string] = up_count; (*iter)[peer_cols.upload_request_count_string] = up_count;
(*iter)[peer_cols.download_request_count_number] = peer->activeReqsToPeer; (*iter)[peer_cols.download_request_count_number] = peer->activeReqsToPeer;
(*iter)[peer_cols.download_request_count_string] = down_count; (*iter)[peer_cols.download_request_count_string] = down_count;
(*iter)[peer_cols.download_rate_double] = peer->rateToClient_KBps; (*iter)[peer_cols.download_rate_speed] = down_speed;
(*iter)[peer_cols.download_rate_string] = down_speed; (*iter)[peer_cols.download_rate_string] = down_speed_string;
(*iter)[peer_cols.upload_rate_double] = peer->rateToPeer_KBps; (*iter)[peer_cols.upload_rate_speed] = up_speed;
(*iter)[peer_cols.upload_rate_string] = up_speed; (*iter)[peer_cols.upload_rate_string] = up_speed_string;
(*iter)[peer_cols.flags] = std::data(peer->flagStr); (*iter)[peer_cols.flags] = std::data(peer->flagStr);
(*iter)[peer_cols.was_updated] = true; (*iter)[peer_cols.was_updated] = true;
(*iter)[peer_cols.blocks_downloaded_count_number] = peer->blocksToClient; (*iter)[peer_cols.blocks_downloaded_count_number] = peer->blocksToClient;
@ -1425,11 +1432,11 @@ void DetailsDialog::Impl::refreshWebseedList(std::vector<tr_torrent*> const& tor
auto const key = make_key(tor, webseed.url); auto const key = make_key(tor, webseed.url);
auto const iter = store->get_iter(hash.at(key).get_path()); auto const iter = store->get_iter(hash.at(key).get_path());
auto const KBps = double(webseed.download_bytes_per_second) / speed_K; auto const speed = Speed{ webseed.download_bytes_per_second, Speed::Units::Byps };
auto const buf = webseed.is_downloading ? Speed{ KBps, Speed::Units::KByps }.to_string() : std::string{}; auto const speed_string = webseed.is_downloading ? speed.to_string() : std::string{};
(*iter)[webseed_cols.download_rate_double] = KBps; (*iter)[webseed_cols.download_rate_speed] = speed;
(*iter)[webseed_cols.download_rate_string] = buf; (*iter)[webseed_cols.download_rate_string] = speed_string;
(*iter)[webseed_cols.was_updated] = true; (*iter)[webseed_cols.was_updated] = true;
} }
} }
@ -1577,25 +1584,9 @@ void setPeerViewColumns(Gtk::TreeView* peer_view)
if (more) if (more)
{ {
view_columns.push_back(&peer_cols.download_request_count_string); view_columns.push_back(&peer_cols.download_request_count_string);
}
if (more)
{
view_columns.push_back(&peer_cols.blocks_downloaded_count_string); view_columns.push_back(&peer_cols.blocks_downloaded_count_string);
}
if (more)
{
view_columns.push_back(&peer_cols.blocks_uploaded_count_string); view_columns.push_back(&peer_cols.blocks_uploaded_count_string);
}
if (more)
{
view_columns.push_back(&peer_cols.reqs_cancelled_by_client_count_string); view_columns.push_back(&peer_cols.reqs_cancelled_by_client_count_string);
}
if (more)
{
view_columns.push_back(&peer_cols.reqs_cancelled_by_peer_count_string); view_columns.push_back(&peer_cols.reqs_cancelled_by_peer_count_string);
} }
@ -1683,7 +1674,7 @@ void setPeerViewColumns(Gtk::TreeView* peer_view)
r->property_xalign() = 1.0F; r->property_xalign() = 1.0F;
c = Gtk::make_managed<Gtk::TreeViewColumn>(_("Down"), *r); c = Gtk::make_managed<Gtk::TreeViewColumn>(_("Down"), *r);
c->add_attribute(r->property_text(), *col); c->add_attribute(r->property_text(), *col);
sort_col = &peer_cols.download_rate_double; sort_col = &peer_cols.download_rate_speed;
} }
else if (*col == peer_cols.upload_rate_string) else if (*col == peer_cols.upload_rate_string)
{ {
@ -1691,7 +1682,7 @@ void setPeerViewColumns(Gtk::TreeView* peer_view)
r->property_xalign() = 1.0F; r->property_xalign() = 1.0F;
c = Gtk::make_managed<Gtk::TreeViewColumn>(_("Up"), *r); c = Gtk::make_managed<Gtk::TreeViewColumn>(_("Up"), *r);
c->add_attribute(r->property_text(), *col); c->add_attribute(r->property_text(), *col);
sort_col = &peer_cols.upload_rate_double; sort_col = &peer_cols.upload_rate_speed;
} }
else if (*col == peer_cols.client) else if (*col == peer_cols.client)
{ {
@ -1761,7 +1752,7 @@ void DetailsDialog::Impl::peer_page_init(Glib::RefPtr<Gtk::Builder> const& build
auto* r = Gtk::make_managed<Gtk::CellRendererText>(); auto* r = Gtk::make_managed<Gtk::CellRendererText>();
auto* c = Gtk::make_managed<Gtk::TreeViewColumn>(_("Down"), *r); auto* c = Gtk::make_managed<Gtk::TreeViewColumn>(_("Down"), *r);
c->add_attribute(r->property_text(), webseed_cols.download_rate_string); c->add_attribute(r->property_text(), webseed_cols.download_rate_string);
c->set_sort_column(webseed_cols.download_rate_double); c->set_sort_column(webseed_cols.download_rate_speed);
v->append_column(*c); v->append_column(*c);
} }

View File

@ -792,9 +792,9 @@ void MainWindow::Impl::updateSpeeds()
if (session != nullptr) if (session != nullptr)
{ {
auto dn_count = int{}; auto dn_count = int{};
auto dn_speed = double{}; auto dn_speed = Speed{};
auto up_count = int{}; auto up_count = int{};
auto up_speed = double{}; auto up_speed = Speed{};
auto const model = core_->get_model(); auto const model = core_->get_model();
for (auto i = 0U, count = model->get_n_items(); i < count; ++i) for (auto i = 0U, count = model->get_n_items(); i < count; ++i)
@ -806,13 +806,10 @@ void MainWindow::Impl::updateSpeeds()
up_speed += torrent->get_speed_up(); up_speed += torrent->get_speed_up();
} }
dl_lb_->set_text(fmt::format( dl_lb_->set_text(fmt::format(fmt::runtime(_("{download_speed} ▼")), fmt::arg("download_speed", dn_speed.to_string())));
_("{download_speed} ▼"),
fmt::arg("download_speed", Speed{ dn_speed, Speed::Units::KByps }.to_string())));
dl_lb_->set_visible(dn_count > 0); dl_lb_->set_visible(dn_count > 0);
ul_lb_->set_text( ul_lb_->set_text(fmt::format(fmt::runtime(_("{upload_speed} ▲")), fmt::arg("upload_speed", up_speed.to_string())));
fmt::format(_("{upload_speed} ▲"), fmt::arg("upload_speed", Speed{ up_speed, Speed::Units::KByps }.to_string())));
ul_lb_->set_visible(dn_count > 0 || up_count > 0); ul_lb_->set_visible(dn_count > 0 || up_count > 0);
} }
} }

View File

@ -49,6 +49,8 @@
#include <sstream> #include <sstream>
#include <string> #include <string>
using namespace libtransmission::Values;
/** /**
*** ***
**/ **/
@ -840,20 +842,22 @@ public:
SpeedPage::SpeedPage(BaseObjectType* cast_item, Glib::RefPtr<Gtk::Builder> const& builder, Glib::RefPtr<Session> const& core) SpeedPage::SpeedPage(BaseObjectType* cast_item, Glib::RefPtr<Gtk::Builder> const& builder, Glib::RefPtr<Session> const& core)
: PageBase(cast_item, builder, core) : PageBase(cast_item, builder, core)
{ {
auto const speed_units_kbyps_str = Speed::units().display_name(Speed::Units::KByps);
localize_label( localize_label(
*init_check_button("upload_limit_check", TR_KEY_speed_limit_up_enabled), *init_check_button("upload_limit_check", TR_KEY_speed_limit_up_enabled),
fmt::arg("speed_units", speed_K_str)); fmt::arg("speed_units", speed_units_kbyps_str));
init_spin_button("upload_limit_spin", TR_KEY_speed_limit_up, 0, std::numeric_limits<int>::max(), 5); init_spin_button("upload_limit_spin", TR_KEY_speed_limit_up, 0, std::numeric_limits<int>::max(), 5);
localize_label( localize_label(
*init_check_button("download_limit_check", TR_KEY_speed_limit_down_enabled), *init_check_button("download_limit_check", TR_KEY_speed_limit_down_enabled),
fmt::arg("speed_units", speed_K_str)); fmt::arg("speed_units", speed_units_kbyps_str));
init_spin_button("download_limit_spin", TR_KEY_speed_limit_down, 0, std::numeric_limits<int>::max(), 5); init_spin_button("download_limit_spin", TR_KEY_speed_limit_down, 0, std::numeric_limits<int>::max(), 5);
localize_label(*get_widget<Gtk::Label>("alt_upload_limit_label"), fmt::arg("speed_units", speed_K_str)); localize_label(*get_widget<Gtk::Label>("alt_upload_limit_label"), fmt::arg("speed_units", speed_units_kbyps_str));
init_spin_button("alt_upload_limit_spin", TR_KEY_alt_speed_up, 0, std::numeric_limits<int>::max(), 5); init_spin_button("alt_upload_limit_spin", TR_KEY_alt_speed_up, 0, std::numeric_limits<int>::max(), 5);
localize_label(*get_widget<Gtk::Label>("alt_download_limit_label"), fmt::arg("speed_units", speed_K_str)); localize_label(*get_widget<Gtk::Label>("alt_download_limit_label"), fmt::arg("speed_units", speed_units_kbyps_str));
init_spin_button("alt_download_limit_spin", TR_KEY_alt_speed_down, 0, std::numeric_limits<int>::max(), 5); init_spin_button("alt_download_limit_spin", TR_KEY_alt_speed_down, 0, std::numeric_limits<int>::max(), 5);
init_time_combo("alt_speed_start_time_combo", TR_KEY_alt_speed_time_begin); init_time_combo("alt_speed_start_time_combo", TR_KEY_alt_speed_time_begin);

View File

@ -140,12 +140,15 @@ public:
std::string_view mime_type; std::string_view mime_type;
uint64_t have_unchecked = {}; Storage have_unchecked = {};
uint64_t have_valid = {}; Storage have_valid = {};
uint64_t left_until_done = {}; Storage left_until_done = {};
uint64_t size_when_done = {}; Storage size_when_done = {};
uint64_t total_size = {}; Storage total_size = {};
uint64_t uploaded_ever = {}; Storage uploaded_ever = {};
Speed speed_down = {};
Speed speed_up = {};
size_t queue_position = {}; size_t queue_position = {};
@ -174,8 +177,6 @@ public:
float ratio = {}; float ratio = {};
float seed_ratio = {}; float seed_ratio = {};
float speed_down = {};
float speed_up = {};
tr_priority_t priority = {}; tr_priority_t priority = {};
@ -247,8 +248,16 @@ Torrent::ChangeFlags Torrent::Impl::update_cache()
auto const view = tr_torrentView(raw_torrent_); auto const view = tr_torrentView(raw_torrent_);
update_cache_value(cache_.name, view.name, result, ChangeFlag::NAME); update_cache_value(cache_.name, view.name, result, ChangeFlag::NAME);
update_cache_value(cache_.speed_up, stats->pieceUploadSpeed_KBps, 0.01F, result, ChangeFlag::SPEED_UP); update_cache_value(
update_cache_value(cache_.speed_down, stats->pieceDownloadSpeed_KBps, 0.01F, result, ChangeFlag::SPEED_DOWN); cache_.speed_up,
Speed{ stats->pieceUploadSpeed_KBps, Speed::Units::KByps },
result,
ChangeFlag::SPEED_UP);
update_cache_value(
cache_.speed_down,
Speed{ stats->pieceDownloadSpeed_KBps, Speed::Units::KByps },
result,
ChangeFlag::SPEED_DOWN);
update_cache_value(cache_.active_peers_up, stats->peersGettingFromUs, result, ChangeFlag::ACTIVE_PEERS_UP); update_cache_value(cache_.active_peers_up, stats->peersGettingFromUs, result, ChangeFlag::ACTIVE_PEERS_UP);
update_cache_value( update_cache_value(
cache_.active_peers_down, cache_.active_peers_down,
@ -294,16 +303,36 @@ Torrent::ChangeFlags Torrent::Impl::update_cache()
Percents(stats->seedRatioPercentDone), Percents(stats->seedRatioPercentDone),
result, result,
ChangeFlag::SEED_RATIO_PERCENT_DONE); ChangeFlag::SEED_RATIO_PERCENT_DONE);
update_cache_value(cache_.total_size, view.total_size, result, ChangeFlag::TOTAL_SIZE); update_cache_value(cache_.total_size, Storage{ view.total_size, Storage::Units::Bytes }, result, ChangeFlag::TOTAL_SIZE);
update_cache_value(cache_.has_seed_ratio, has_seed_ratio, result, ChangeFlag::LONG_PROGRESS); update_cache_value(cache_.has_seed_ratio, has_seed_ratio, result, ChangeFlag::LONG_PROGRESS);
update_cache_value(cache_.have_unchecked, stats->haveUnchecked, result, ChangeFlag::LONG_PROGRESS); update_cache_value(
update_cache_value(cache_.have_valid, stats->haveValid, result, ChangeFlag::LONG_PROGRESS); cache_.have_unchecked,
update_cache_value(cache_.left_until_done, stats->leftUntilDone, result, ChangeFlag::LONG_PROGRESS); Storage{ stats->haveUnchecked, Storage::Units::Bytes },
result,
ChangeFlag::LONG_PROGRESS);
update_cache_value(
cache_.have_valid,
Storage{ stats->haveValid, Storage::Units::Bytes },
result,
ChangeFlag::LONG_PROGRESS);
update_cache_value(
cache_.left_until_done,
Storage{ stats->leftUntilDone, Storage::Units::Bytes },
result,
ChangeFlag::LONG_PROGRESS);
update_cache_value(cache_.percent_done, Percents(stats->percentDone), result, ChangeFlag::LONG_PROGRESS); update_cache_value(cache_.percent_done, Percents(stats->percentDone), result, ChangeFlag::LONG_PROGRESS);
update_cache_value(cache_.seed_ratio, static_cast<float>(seed_ratio), 0.01F, result, ChangeFlag::LONG_PROGRESS); update_cache_value(cache_.seed_ratio, static_cast<float>(seed_ratio), 0.01F, result, ChangeFlag::LONG_PROGRESS);
update_cache_value(cache_.size_when_done, stats->sizeWhenDone, result, ChangeFlag::LONG_PROGRESS); update_cache_value(
update_cache_value(cache_.uploaded_ever, stats->uploadedEver, result, ChangeFlag::LONG_PROGRESS); cache_.size_when_done,
Storage{ stats->sizeWhenDone, Storage::Units::Bytes },
result,
ChangeFlag::LONG_PROGRESS);
update_cache_value(
cache_.uploaded_ever,
Storage{ stats->uploadedEver, Storage::Units::Bytes },
result,
ChangeFlag::LONG_PROGRESS);
update_cache_value( update_cache_value(
cache_.metadata_percent_complete, cache_.metadata_percent_complete,
@ -426,7 +455,7 @@ Glib::ustring Torrent::Impl::get_long_progress_text() const
{ {
Glib::ustring gstr; Glib::ustring gstr;
bool const isDone = cache_.left_until_done == 0; bool const isDone = cache_.left_until_done.is_zero();
auto const haveTotal = cache_.have_unchecked + cache_.have_valid; auto const haveTotal = cache_.have_unchecked + cache_.have_valid;
bool const isSeed = cache_.have_valid >= cache_.total_size; bool const isSeed = cache_.have_valid >= cache_.total_size;
@ -585,16 +614,14 @@ Glib::ustring Torrent::Impl::get_short_transfer_text() const
if (cache_.has_metadata && cache_.active_peers_down > 0) if (cache_.has_metadata && cache_.active_peers_down > 0)
{ {
return fmt::format( return fmt::format(
_("{download_speed} ▼ {upload_speed} ▲"), fmt::runtime(_("{download_speed} ▼ {upload_speed} ▲")),
fmt::arg("upload_speed", Speed{ cache_.speed_up, Speed::Units::KByps }.to_string()), fmt::arg("upload_speed", cache_.speed_up.to_string()),
fmt::arg("download_speed", Speed{ cache_.speed_down, Speed::Units::KByps }.to_string())); fmt::arg("download_speed", cache_.speed_down.to_string()));
} }
if (cache_.has_metadata && cache_.active_peers_up > 0) if (cache_.has_metadata && cache_.active_peers_up > 0)
{ {
return fmt::format( return fmt::format(fmt::runtime(_("{upload_speed} ▲")), fmt::arg("upload_speed", cache_.speed_up.to_string()));
_("{upload_speed} ▲"),
fmt::arg("upload_speed", Speed{ cache_.speed_up, Speed::Units::KByps }.to_string()));
} }
if (cache_.stalled) if (cache_.stalled)
@ -720,12 +747,12 @@ tr_torrent& Torrent::get_underlying() const
return *impl_->get_raw_torrent(); return *impl_->get_raw_torrent();
} }
float Torrent::get_speed_up() const Speed Torrent::get_speed_up() const
{ {
return impl_->get_cache().speed_up; return impl_->get_cache().speed_up;
} }
float Torrent::get_speed_down() const Speed Torrent::get_speed_down() const
{ {
return impl_->get_cache().speed_down; return impl_->get_cache().speed_down;
} }
@ -790,7 +817,7 @@ int Torrent::get_active_peer_count() const
return impl_->get_cache().active_peer_count; return impl_->get_cache().active_peer_count;
} }
uint64_t Torrent::get_total_size() const Storage Torrent::get_total_size() const
{ {
return impl_->get_cache().total_size; return impl_->get_cache().total_size;
} }

View File

@ -8,6 +8,7 @@
#include "Flags.h" #include "Flags.h"
#include <libtransmission/transmission.h> #include <libtransmission/transmission.h>
#include <libtransmission/values.h>
#include <giomm/icon.h> #include <giomm/icon.h>
#include <glibmm/extraclassinit.h> #include <glibmm/extraclassinit.h>
@ -71,6 +72,9 @@ public:
using ChangeFlags = Flags<ChangeFlag>; using ChangeFlags = Flags<ChangeFlag>;
public: public:
using Speed = libtransmission::Values::Speed;
using Storage = libtransmission::Values::Storage;
int get_active_peer_count() const; int get_active_peer_count() const;
int get_active_peers_down() const; int get_active_peers_down() const;
int get_active_peers_up() const; int get_active_peers_up() const;
@ -92,10 +96,10 @@ public:
float get_ratio() const; float get_ratio() const;
Percents get_recheck_progress() const; Percents get_recheck_progress() const;
Percents get_seed_ratio_percent_done() const; Percents get_seed_ratio_percent_done() const;
float get_speed_down() const; Speed get_speed_down() const;
float get_speed_up() const; Speed get_speed_up() const;
tr_torrent& get_underlying() const; tr_torrent& get_underlying() const;
uint64_t get_total_size() const; Storage get_total_size() const;
unsigned int get_trackers() const; unsigned int get_trackers() const;
Glib::RefPtr<Gio::Icon> get_icon() const; Glib::RefPtr<Gio::Icon> get_icon() const;

View File

@ -61,28 +61,6 @@ using namespace std::literals;
using namespace libtransmission::Values; using namespace libtransmission::Values;
/***
**** UNITS
***/
int const mem_K = 1024;
char const* const mem_K_str = N_("KiB");
char const* const mem_M_str = N_("MiB");
char const* const mem_G_str = N_("GiB");
char const* const mem_T_str = N_("TiB");
int const disk_K = 1000;
char const* const disk_K_str = N_("kB");
char const* const disk_M_str = N_("MB");
char const* const disk_G_str = N_("GB");
char const* const disk_T_str = N_("TB");
int const speed_K = 1000;
char const* const speed_K_str = N_("kB/s");
char const* const speed_M_str = N_("MB/s");
char const* const speed_G_str = N_("GB/s");
char const* const speed_T_str = N_("TB/s");
/*** /***
**** ****
***/ ***/
@ -135,9 +113,14 @@ Glib::ustring tr_strlratio(double ratio)
return tr_strratio(ratio, gtr_get_unicode_string(GtrUnicode::Inf).c_str()); return tr_strratio(ratio, gtr_get_unicode_string(GtrUnicode::Inf).c_str());
} }
Glib::ustring tr_strlsize(libtransmission::Values::Storage const& storage)
{
return storage.is_zero() ? Q_("None") : storage.to_string();
}
Glib::ustring tr_strlsize(guint64 n_bytes) Glib::ustring tr_strlsize(guint64 n_bytes)
{ {
return n_bytes == 0 ? Q_("None") : Storage{ n_bytes, Storage::Units::Bytes }.to_string(); return tr_strlsize(Storage{ n_bytes, Storage::Units::Bytes });
} }
namespace namespace

View File

@ -9,6 +9,7 @@
#include <libtransmission/transmission.h> #include <libtransmission/transmission.h>
#include <libtransmission/tr-macros.h> #include <libtransmission/tr-macros.h>
#include <libtransmission/values.h>
#include <glibmm/objectbase.h> #include <glibmm/objectbase.h>
#include <glibmm/refptr.h> #include <glibmm/refptr.h>
@ -43,28 +44,6 @@
**** ****
***/ ***/
extern int const mem_K;
extern char const* const mem_K_str;
extern char const* const mem_M_str;
extern char const* const mem_G_str;
extern char const* const mem_T_str;
extern int const disk_K;
extern char const* const disk_K_str;
extern char const* const disk_M_str;
extern char const* const disk_G_str;
extern char const* const disk_T_str;
extern int const speed_K;
extern char const* const speed_K_str;
extern char const* const speed_M_str;
extern char const* const speed_G_str;
extern char const* const speed_T_str;
/***
****
***/
void gtr_message(std::string const& message); void gtr_message(std::string const& message);
void gtr_warning(std::string const& message); void gtr_warning(std::string const& message);
void gtr_error(std::string const& message); void gtr_error(std::string const& message);
@ -85,6 +64,7 @@ Glib::ustring gtr_get_unicode_string(GtrUnicode uni);
/* return a human-readable string for the size given in bytes. */ /* return a human-readable string for the size given in bytes. */
Glib::ustring tr_strlsize(guint64 size_in_bytes); Glib::ustring tr_strlsize(guint64 size_in_bytes);
Glib::ustring tr_strlsize(libtransmission::Values::Storage const& storage);
/* return a human-readable string for the given ratio. */ /* return a human-readable string for the given ratio. */
Glib::ustring tr_strlratio(double ratio); Glib::ustring tr_strlratio(double ratio);

View File

@ -32,7 +32,6 @@
namespace namespace
{ {
auto const* const AppConfigDirName = "transmission"; auto const* const AppConfigDirName = "transmission";
auto const* const AppTranslationDomainName = "transmission-gtk"; auto const* const AppTranslationDomainName = "transmission-gtk";
auto const* const AppName = "transmission-gtk"; auto const* const AppName = "transmission-gtk";
@ -45,7 +44,6 @@ Glib::OptionEntry create_option_entry(Glib::ustring const& long_name, gchar shor
entry.set_description(description); entry.set_description(description);
return entry; return entry;
} }
} // namespace } // namespace
int main(int argc, char** argv) int main(int argc, char** argv)
@ -117,10 +115,11 @@ int main(int argc, char** argv)
return 0; return 0;
} }
/* init the unit formatters */ // init the unit formatters
tr_formatter_mem_init(mem_K, _(mem_K_str), _(mem_M_str), _(mem_G_str), _(mem_T_str)); using Config = libtransmission::Values::Config;
tr_formatter_size_init(disk_K, _(disk_K_str), _(disk_M_str), _(disk_G_str), _(disk_T_str)); Config::Speed = { Config::Base::Kilo, _("B/s"), _("kB/s"), _("MB/s"), _("GB/s"), _("TB/s") };
tr_formatter_speed_init(speed_K, _(speed_K_str), _(speed_M_str), _(speed_G_str), _(speed_T_str)); Config::Memory = { Config::Base::Kibi, _("B"), _("KiB"), _("MiB"), _("GiB"), _("TiB") };
Config::Storage = { Config::Base::Kilo, _("B"), _("kB"), _("MB"), _("GB"), _("TB") };
/* set up the config dir */ /* set up the config dir */
if (std::empty(config_dir)) if (std::empty(config_dir))

View File

@ -1172,14 +1172,14 @@ private:
[[nodiscard]] constexpr bool is_piece_transfer_allowed(tr_direction direction) const noexcept [[nodiscard]] constexpr bool is_piece_transfer_allowed(tr_direction direction) const noexcept
{ {
if (uses_speed_limit(direction) && speed_limit(direction).base_quantity() == 0U) if (uses_speed_limit(direction) && speed_limit(direction).is_zero())
{ {
return false; return false;
} }
if (uses_session_limits()) if (uses_session_limits())
{ {
if (auto const limit = session->active_speed_limit(direction); limit && limit->base_quantity() == 0U) if (auto const limit = session->active_speed_limit(direction); limit && limit->is_zero())
{ {
return false; return false;
} }

View File

@ -64,6 +64,18 @@ time_t libtransmission::detail::tr_time::current_time = {};
// --- // ---
namespace libtransmission::Values
{
// default values; can be overridden by client apps
Config::Units<MemoryUnits> Config::Memory{ Config::Base::Kibi, "B"sv, "KiB"sv, "MiB"sv, "GiB"sv, "TiB"sv };
Config::Units<SpeedUnits> Config::Speed{ Config::Base::Kilo, "B/s"sv, "kB/s"sv, "MB/s"sv, "GB/s"sv, "TB/s"sv };
Config::Units<StorageUnits> Config::Storage{ Config::Base::Kilo, "B"sv, "kB"sv, "MB"sv, "GB"sv, "TB"sv };
} // namespace libtransmission::Values
// ---
std::optional<std::locale> tr_locale_set_global(char const* locale_name) noexcept std::optional<std::locale> tr_locale_set_global(char const* locale_name) noexcept
{ {
try try
@ -666,42 +678,6 @@ uint64_t tr_ntohll(uint64_t netlonglong)
#endif #endif
} }
// --- VALUES / FORMATTER
namespace libtransmission::Values
{
// default values; can be overridden by client apps
Config::Units<MemoryUnits> Config::Memory{ Config::Base::Kibi, "B"sv, "KiB"sv, "MiB"sv, "GiB"sv, "TiB"sv };
Config::Units<SpeedUnits> Config::Speed{ Config::Base::Kilo, "B/s"sv, "kB/s"sv, "MB/s"sv, "GB/s"sv, "TB/s"sv };
Config::Units<StorageUnits> Config::Storage{ Config::Base::Kilo, "B"sv, "kB"sv, "MB"sv, "GB"sv, "TB"sv };
} // namespace libtransmission::Values
void tr_formatter_size_init(size_t base, char const* kb, char const* mb, char const* gb, char const* tb)
{
namespace Values = libtransmission::Values;
auto const kval = base == 1000U ? Values::Config::Base::Kilo : Values::Config::Base::Kibi;
Values::Config::Storage = { kval, "B", kb, mb, gb, tb };
}
void tr_formatter_speed_init(size_t base, char const* kb, char const* mb, char const* gb, char const* tb)
{
namespace Values = libtransmission::Values;
auto const kval = base == 1000U ? Values::Config::Base::Kilo : Values::Config::Base::Kibi;
Values::Config::Speed = { kval, "B/s", kb, mb, gb, tb };
}
void tr_formatter_mem_init(size_t base, char const* kb, char const* mb, char const* gb, char const* tb)
{
namespace Values = libtransmission::Values;
auto const kval = base == 1000U ? Values::Config::Base::Kilo : Values::Config::Base::Kibi;
Values::Config::Memory = { kval, "B", kb, mb, gb, tb };
}
// --- ENVIRONMENT // --- ENVIRONMENT
bool tr_env_key_exists(char const* key) bool tr_env_key_exists(char const* key)

View File

@ -300,13 +300,6 @@ constexpr void tr_timeUpdate(time_t now) noexcept
// --- // ---
/* example: tr_formatter_size_init(1024, _("KiB"), _("MiB"), _("GiB"), _("TiB")); */
void tr_formatter_size_init(size_t base, char const* kb, char const* mb, char const* gb, char const* tb);
void tr_formatter_speed_init(size_t base, char const* kb, char const* mb, char const* gb, char const* tb);
void tr_formatter_mem_init(size_t base, char const* kb, char const* mb, char const* gb, char const* tb);
// ---
/** @brief Check if environment variable exists. */ /** @brief Check if environment variable exists. */
[[nodiscard]] bool tr_env_key_exists(char const* key); [[nodiscard]] bool tr_env_key_exists(char const* key);

View File

@ -65,6 +65,11 @@ struct Config
return std::string_view{ units < std::size(display_names_) ? std::data(display_names_[units]) : "" }; return std::string_view{ units < std::size(display_names_) ? std::data(display_names_[units]) : "" };
} }
[[nodiscard]] constexpr auto display_name(UnitsEnum multiplier) const noexcept
{
return display_name(static_cast<size_t>(multiplier));
}
[[nodiscard]] constexpr auto multiplier(UnitsEnum multiplier) const noexcept [[nodiscard]] constexpr auto multiplier(UnitsEnum multiplier) const noexcept
{ {
return multipliers_[static_cast<int>(multiplier)]; return multipliers_[static_cast<int>(multiplier)];
@ -122,6 +127,11 @@ public:
return base_quantity_; return base_quantity_;
} }
[[nodiscard]] constexpr auto is_zero() const noexcept
{
return base_quantity_ == 0U;
}
[[nodiscard]] constexpr auto count(Units tgt) const noexcept [[nodiscard]] constexpr auto count(Units tgt) const noexcept
{ {
return base_quantity_ / (1.0 * units_.multiplier(tgt)); return base_quantity_ / (1.0 * units_.multiplier(tgt));
@ -133,7 +143,7 @@ public:
return *this; return *this;
} }
[[nodiscard]] constexpr auto operator+(Value const& that) noexcept [[nodiscard]] constexpr auto operator+(Value const& that) const noexcept
{ {
auto ret = *this; auto ret = *this;
return ret += that; return ret += that;
@ -145,7 +155,7 @@ public:
return *this; return *this;
} }
[[nodiscard]] constexpr auto operator*(uint64_t mult) noexcept [[nodiscard]] constexpr auto operator*(uint64_t mult) const noexcept
{ {
auto ret = *this; auto ret = *this;
return ret *= mult; return ret *= mult;
@ -157,7 +167,7 @@ public:
return *this; return *this;
} }
[[nodiscard]] constexpr auto operator/(uint64_t mult) noexcept [[nodiscard]] constexpr auto operator/(uint64_t mult) const noexcept
{ {
auto ret = *this; auto ret = *this;
return ret /= mult; return ret /= mult;

View File

@ -16,6 +16,7 @@
#include <libtransmission/log.h> #include <libtransmission/log.h>
#include <libtransmission/torrent-metainfo.h> #include <libtransmission/torrent-metainfo.h>
#include <libtransmission/utils.h> #include <libtransmission/utils.h>
#include <libtransmission/values.h>
#include <libtransmission/variant.h> #include <libtransmission/variant.h>
#import "VDKQueue.h" #import "VDKQueue.h"
@ -126,6 +127,41 @@ static NSString* const kDonateURL = @"https://transmissionbt.com/donate/";
static NSTimeInterval const kDonateNagTime = 60 * 60 * 24 * 7; static NSTimeInterval const kDonateNagTime = 60 * 60 * 24 * 7;
static void initUnits()
{
using Config = libtransmission::Values::Config;
// use a random value to avoid possible pluralization issues with 1 or 0 (an example is if we use 1 for bytes,
// we'd get "byte" when we'd want "bytes" for the generic libtransmission value at least)
int const ArbitraryPluralNumber = 17;
NSByteCountFormatter* unitFormatter = [[NSByteCountFormatter alloc] init];
unitFormatter.includesCount = NO;
unitFormatter.allowsNonnumericFormatting = NO;
unitFormatter.allowedUnits = NSByteCountFormatterUseBytes;
NSString* b_str = [unitFormatter stringFromByteCount:ArbitraryPluralNumber];
unitFormatter.allowedUnits = NSByteCountFormatterUseKB;
NSString* k_str = [unitFormatter stringFromByteCount:ArbitraryPluralNumber];
unitFormatter.allowedUnits = NSByteCountFormatterUseMB;
NSString* m_str = [unitFormatter stringFromByteCount:ArbitraryPluralNumber];
unitFormatter.allowedUnits = NSByteCountFormatterUseGB;
NSString* g_str = [unitFormatter stringFromByteCount:ArbitraryPluralNumber];
unitFormatter.allowedUnits = NSByteCountFormatterUseTB;
NSString* t_str = [unitFormatter stringFromByteCount:ArbitraryPluralNumber];
Config::Memory = { Config::Base::Kilo, b_str.UTF8String, k_str.UTF8String,
m_str.UTF8String, g_str.UTF8String, t_str.UTF8String };
Config::Storage = { Config::Base::Kilo, b_str.UTF8String, k_str.UTF8String,
m_str.UTF8String, g_str.UTF8String, t_str.UTF8String };
b_str = NSLocalizedString(@"B/s", "Transfer speed (bytes per second)");
k_str = NSLocalizedString(@"KB/s", "Transfer speed (kilobytes per second)");
m_str = NSLocalizedString(@"MB/s", "Transfer speed (megabytes per second)");
g_str = NSLocalizedString(@"GB/s", "Transfer speed (gigabytes per second)");
t_str = NSLocalizedString(@"TB/s", "Transfer speed (terabytes per second)");
Config::Speed = { Config::Base::Kilo, b_str.UTF8String, k_str.UTF8String,
m_str.UTF8String, g_str.UTF8String, t_str.UTF8String };
}
static void altSpeedToggledCallback([[maybe_unused]] tr_session* handle, bool active, bool byUser, void* controller) static void altSpeedToggledCallback([[maybe_unused]] tr_session* handle, bool active, bool byUser, void* controller)
{ {
NSDictionary* dict = @{@"Active" : @(active), @"ByUser" : @(byUser)}; NSDictionary* dict = @{@"Active" : @(active), @"ByUser" : @(byUser)};
@ -514,34 +550,7 @@ void onTorrentCompletenessChanged(tr_torrent* tor, tr_completeness status, bool
tr_variantDictAddStr(&settings, TR_KEY_rpc_host_whitelist, [_fDefaults stringForKey:@"RPCHostWhitelist"].UTF8String); tr_variantDictAddStr(&settings, TR_KEY_rpc_host_whitelist, [_fDefaults stringForKey:@"RPCHostWhitelist"].UTF8String);
} }
NSByteCountFormatter* unitFormatter = [[NSByteCountFormatter alloc] init]; initUnits();
unitFormatter.includesCount = NO;
unitFormatter.allowsNonnumericFormatting = NO;
unitFormatter.allowedUnits = NSByteCountFormatterUseKB;
// use a random value to avoid possible pluralization issues with 1 or 0 (an example is if we use 1 for bytes,
// we'd get "byte" when we'd want "bytes" for the generic libtransmission value at least)
NSString* kbString = [unitFormatter stringFromByteCount:17];
unitFormatter.allowedUnits = NSByteCountFormatterUseMB;
NSString* mbString = [unitFormatter stringFromByteCount:17];
unitFormatter.allowedUnits = NSByteCountFormatterUseGB;
NSString* gbString = [unitFormatter stringFromByteCount:17];
unitFormatter.allowedUnits = NSByteCountFormatterUseTB;
NSString* tbString = [unitFormatter stringFromByteCount:17];
tr_formatter_size_init(1000, kbString.UTF8String, mbString.UTF8String, gbString.UTF8String, tbString.UTF8String);
tr_formatter_speed_init(
1000,
NSLocalizedString(@"KB/s", "Transfer speed (kilobytes per second)").UTF8String,
NSLocalizedString(@"MB/s", "Transfer speed (megabytes per second)").UTF8String,
NSLocalizedString(@"GB/s", "Transfer speed (gigabytes per second)").UTF8String,
NSLocalizedString(@"TB/s", "Transfer speed (terabytes per second)").UTF8String); //why not?
tr_formatter_mem_init(1000, kbString.UTF8String, mbString.UTF8String, gbString.UTF8String, tbString.UTF8String);
auto const default_config_dir = tr_getDefaultConfigDir("Transmission"); auto const default_config_dir = tr_getDefaultConfigDir("Transmission");
_fLib = tr_sessionInit(default_config_dir.c_str(), YES, settings); _fLib = tr_sessionInit(default_config_dir.c_str(), YES, settings);

View File

@ -29,6 +29,7 @@
#include <libtransmission/tr-getopt.h> #include <libtransmission/tr-getopt.h>
#include <libtransmission/utils.h> #include <libtransmission/utils.h>
#include <libtransmission/values.h>
#include <libtransmission/version.h> #include <libtransmission/version.h>
#include "AddData.h" #include "AddData.h"
@ -99,6 +100,7 @@ Application::Application(int& argc, char** argv)
{ {
setApplicationName(config_name_); setApplicationName(config_name_);
loadTranslations(); loadTranslations();
initUnits();
#if defined(_WIN32) || defined(__APPLE__) #if defined(_WIN32) || defined(__APPLE__)
@ -403,6 +405,20 @@ void Application::loadTranslations()
} }
} }
void Application::initUnits()
{
using Config = libtransmission::Values::Config;
Config::Speed = { Config::Base::Kilo, tr("B/s").toStdString(), tr("kB/s").toStdString(),
tr("MB/s").toStdString(), tr("GB/s").toStdString(), tr("TB/s").toStdString() };
Config::Memory = { Config::Base::Kibi, tr("B").toStdString(), tr("KiB").toStdString(),
tr("MiB").toStdString(), tr("GiB").toStdString(), tr("TiB").toStdString() };
Config::Storage = { Config::Base::Kilo, tr("B").toStdString(), tr("kB").toStdString(),
tr("MB").toStdString(), tr("GB").toStdString(), tr("TB").toStdString() };
}
void Application::quitLater() const void Application::quitLater() const
{ {
QTimer::singleShot(0, this, SLOT(quit())); QTimer::singleShot(0, this, SLOT(quit()));

View File

@ -92,6 +92,7 @@ private slots:
private: private:
void maybeUpdateBlocklist() const; void maybeUpdateBlocklist() const;
void loadTranslations(); void loadTranslations();
void initUnits();
QStringList getNames(torrent_ids_t const& ids) const; QStringList getNames(torrent_ids_t const& ids) const;
void quitLater() const; void quitLater() const;
void notifyTorrentAdded(Torrent const*) const; void notifyTorrentAdded(Torrent const*) const;

View File

@ -430,7 +430,6 @@ void DetailsDialog::refreshUI()
auto const mixed = tr("Mixed"); auto const mixed = tr("Mixed");
auto const unknown = tr("Unknown"); auto const unknown = tr("Unknown");
auto const now = time(nullptr); auto const now = time(nullptr);
auto const& fmt = Formatter::get();
// build a list of torrents // build a list of torrents
auto torrents = QList<Torrent const*>{}; auto torrents = QList<Torrent const*>{};
@ -532,14 +531,14 @@ void DetailsDialog::refreshUI()
double const d = size_when_done == 0 ? double const d = size_when_done == 0 ?
100.0 : 100.0 :
100.0 * static_cast<double>(size_when_done - left_until_done) / static_cast<double>(size_when_done); 100.0 * static_cast<double>(size_when_done - left_until_done) / static_cast<double>(size_when_done);
auto const pct = fmt.percentToString(d); auto const pct = Formatter::percent_to_string(d);
auto const size_when_done_str = fmt.sizeToString(size_when_done); auto const size_when_done_str = Formatter::storage_to_string(size_when_done);
if (have_unverified == 0 && left_until_done == 0) if (have_unverified == 0 && left_until_done == 0)
{ {
//: Text following the "Have:" label in torrent properties dialog; //: Text following the "Have:" label in torrent properties dialog;
//: %1 is amount of downloaded and verified data //: %1 is amount of downloaded and verified data
string = tr("%1 (100%)").arg(fmt.sizeToString(have_verified)); string = tr("%1 (100%)").arg(Formatter::storage_to_string(have_verified));
} }
else if (have_unverified == 0) else if (have_unverified == 0)
{ {
@ -547,7 +546,7 @@ void DetailsDialog::refreshUI()
//: %1 is amount of downloaded and verified data, //: %1 is amount of downloaded and verified data,
//: %2 is overall size of torrent data, //: %2 is overall size of torrent data,
//: %3 is percentage (%1/%2*100) //: %3 is percentage (%1/%2*100)
string = tr("%1 of %2 (%3%)").arg(fmt.sizeToString(have_verified)).arg(size_when_done_str).arg(pct); string = tr("%1 of %2 (%3%)").arg(Formatter::storage_to_string(have_verified)).arg(size_when_done_str).arg(pct);
} }
else else
{ {
@ -557,10 +556,10 @@ void DetailsDialog::refreshUI()
//: %3 is percentage (%1/%2*100), //: %3 is percentage (%1/%2*100),
//: %4 is amount of downloaded but not yet verified data //: %4 is amount of downloaded but not yet verified data
string = tr("%1 of %2 (%3%), %4 Unverified") string = tr("%1 of %2 (%3%), %4 Unverified")
.arg(fmt.sizeToString(have_verified + have_unverified)) .arg(Formatter::storage_to_string(have_verified + have_unverified))
.arg(size_when_done_str) .arg(size_when_done_str)
.arg(pct) .arg(pct)
.arg(fmt.sizeToString(have_unverified)); .arg(Formatter::storage_to_string(have_unverified));
} }
} }
@ -574,7 +573,7 @@ void DetailsDialog::refreshUI()
else else
{ {
auto const percent = 100.0 * static_cast<double>(available) / static_cast<double>(size_when_done); auto const percent = 100.0 * static_cast<double>(available) / static_cast<double>(size_when_done);
string = QStringLiteral("%1%").arg(fmt.percentToString(percent)); string = QStringLiteral("%1%").arg(Formatter::percent_to_string(percent));
} }
ui_.availabilityValueLabel->setText(string); ui_.availabilityValueLabel->setText(string);
@ -595,8 +594,8 @@ void DetailsDialog::refreshUI()
f += t->failedEver(); f += t->failedEver();
} }
QString const dstr = fmt.sizeToString(d); auto const dstr = Formatter::storage_to_string(d);
QString const fstr = fmt.sizeToString(f); auto const fstr = Formatter::storage_to_string(f);
if (f != 0) if (f != 0)
{ {
@ -627,8 +626,8 @@ void DetailsDialog::refreshUI()
} }
string = tr("%1 (Ratio: %2)") string = tr("%1 (Ratio: %2)")
.arg(fmt.sizeToString(uploaded)) .arg(Formatter::storage_to_string(uploaded))
.arg(fmt.ratioToString(tr_getRatio(uploaded, denominator))); .arg(Formatter::ratio_to_string(tr_getRatio(uploaded, denominator)));
} }
ui_.uploadedValueLabel->setText(string); ui_.uploadedValueLabel->setText(string);
@ -667,7 +666,7 @@ void DetailsDialog::refreshUI()
else else
{ {
auto const seconds = static_cast<int>(std::difftime(now, baseline)); auto const seconds = static_cast<int>(std::difftime(now, baseline));
string = fmt.timeToString(seconds); string = Formatter::time_to_string(seconds);
} }
} }
@ -701,7 +700,7 @@ void DetailsDialog::refreshUI()
} }
else else
{ {
string = fmt.timeToString(baseline); string = Formatter::time_to_string(baseline);
} }
} }
} }
@ -739,7 +738,7 @@ void DetailsDialog::refreshUI()
} }
else else
{ {
string = tr("%1 ago").arg(fmt.timeToString(seconds)); string = tr("%1 ago").arg(Formatter::time_to_string(seconds));
} }
} }
@ -802,11 +801,13 @@ void DetailsDialog::refreshUI()
} }
else if (piece_size > 0) else if (piece_size > 0)
{ {
string = tr("%1 (%Ln pieces @ %2)", "", pieces).arg(fmt.sizeToString(size)).arg(fmt.memToString(piece_size)); string = tr("%1 (%Ln pieces @ %2)", "", pieces)
.arg(Formatter::storage_to_string(size))
.arg(Formatter::memory_to_string(piece_size));
} }
else else
{ {
string = tr("%1 (%Ln pieces)", "", pieces).arg(fmt.sizeToString(size)); string = tr("%1 (%Ln pieces)", "", pieces).arg(Formatter::storage_to_string(size));
} }
} }
@ -1449,10 +1450,9 @@ void DetailsDialog::onRemoveTrackerClicked()
void DetailsDialog::initOptionsTab() void DetailsDialog::initOptionsTab()
{ {
auto const speed_unit_str = Formatter::get().unitStr(Formatter::SPEED, Formatter::KB); auto const speed_unit_suffix = QStringLiteral(" %1").arg(Speed::display_name(Speed::Units::KByps));
ui_.singleDownSpin->setSuffix(speed_unit_suffix);
ui_.singleDownSpin->setSuffix(QStringLiteral(" %1").arg(speed_unit_str)); ui_.singleUpSpin->setSuffix(speed_unit_suffix);
ui_.singleUpSpin->setSuffix(QStringLiteral(" %1").arg(speed_unit_str));
ui_.singleDownSpin->setProperty(PrefKey, TR_KEY_downloadLimit); ui_.singleDownSpin->setProperty(PrefKey, TR_KEY_downloadLimit);
ui_.singleUpSpin->setProperty(PrefKey, TR_KEY_uploadLimit); ui_.singleUpSpin->setProperty(PrefKey, TR_KEY_uploadLimit);
@ -1545,12 +1545,14 @@ void DetailsDialog::initTrackerTab()
void DetailsDialog::initPeersTab() void DetailsDialog::initPeersTab()
{ {
auto const speed_width_str = Speed{ 1024U, Speed::Units::MByps }.to_qstring();
ui_.peersView->setHeaderLabels({ QString{}, tr("Up"), tr("Down"), tr("%"), tr("Status"), tr("Address"), tr("Client") }); ui_.peersView->setHeaderLabels({ QString{}, tr("Up"), tr("Down"), tr("%"), tr("Status"), tr("Address"), tr("Client") });
ui_.peersView->sortByColumn(COL_ADDRESS, Qt::AscendingOrder); ui_.peersView->sortByColumn(COL_ADDRESS, Qt::AscendingOrder);
ui_.peersView->setColumnWidth(COL_LOCK, 20); ui_.peersView->setColumnWidth(COL_LOCK, 20);
ui_.peersView->setColumnWidth(COL_UP, measureViewItem(ui_.peersView, COL_UP, QStringLiteral("1024 MiB/s"))); ui_.peersView->setColumnWidth(COL_UP, measureViewItem(ui_.peersView, COL_UP, speed_width_str));
ui_.peersView->setColumnWidth(COL_DOWN, measureViewItem(ui_.peersView, COL_DOWN, QStringLiteral("1024 MiB/s"))); ui_.peersView->setColumnWidth(COL_DOWN, measureViewItem(ui_.peersView, COL_DOWN, speed_width_str));
ui_.peersView->setColumnWidth(COL_PERCENT, measureViewItem(ui_.peersView, COL_PERCENT, QStringLiteral("100%"))); ui_.peersView->setColumnWidth(COL_PERCENT, measureViewItem(ui_.peersView, COL_PERCENT, QStringLiteral("100%")));
ui_.peersView->setColumnWidth(COL_STATUS, measureViewItem(ui_.peersView, COL_STATUS, QStringLiteral("ODUK?EXI"))); ui_.peersView->setColumnWidth(COL_STATUS, measureViewItem(ui_.peersView, COL_STATUS, QStringLiteral("ODUK?EXI")));
ui_.peersView->setColumnWidth(COL_ADDRESS, measureViewItem(ui_.peersView, COL_ADDRESS, QStringLiteral("888.888.888.888"))); ui_.peersView->setColumnWidth(COL_ADDRESS, measureViewItem(ui_.peersView, COL_ADDRESS, QStringLiteral("888.888.888.888")));

View File

@ -220,7 +220,7 @@ double FileTreeItem::progress() const
QString FileTreeItem::sizeString() const QString FileTreeItem::sizeString() const
{ {
return Formatter::get().sizeToString(size()); return Formatter::storage_to_string(size());
} }
uint64_t FileTreeItem::size() const uint64_t FileTreeItem::size() const

View File

@ -22,6 +22,8 @@
#include "Formatter.h" #include "Formatter.h"
#include "Utils.h" #include "Utils.h"
using namespace libtransmission::Values;
namespace namespace
{ {
@ -89,12 +91,11 @@ void FileTreeView::resizeEvent(QResizeEvent* event)
switch (column) switch (column)
{ {
case FileTreeModel::COL_SIZE: case FileTreeModel::COL_SIZE:
for (int s = Formatter::get().B; s <= Formatter::get().TB; ++s) item_texts << QString::fromStdString(Memory{ 999.9, Memory::Units::Bytes }.to_string())
{ << QString::fromStdString(Memory{ 999.9, Memory::Units::KBytes }.to_string())
item_texts << QString::fromStdString(Memory{ 999.9, Memory::Units::MBytes }.to_string())
<< (QStringLiteral("999.9 ") + Formatter::get().unitStr(Formatter::MEM, static_cast<Formatter::Size>(s))); << QString::fromStdString(Memory{ 999.9, Memory::Units::GBytes }.to_string())
} << QString::fromStdString(Memory{ 999.9, Memory::Units::TBytes }.to_string());
break; break;
case FileTreeModel::COL_PROGRESS: case FileTreeModel::COL_PROGRESS:

View File

@ -8,58 +8,13 @@
#include <libtransmission/values.h> #include <libtransmission/values.h>
#include "Formatter.h" #include "Formatter.h"
#include "Speed.h"
#include <algorithm> #include <algorithm>
using namespace std::literals; using namespace std::literals;
using namespace libtransmission::Values; using namespace libtransmission::Values;
Formatter& Formatter::get() QString Formatter::memory_to_string(int64_t const bytes)
{
// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
static auto& singleton = *new Formatter();
return singleton;
}
Formatter::Formatter()
: UnitStrings{ {
{ tr("B/s"), tr("kB/s"), tr("MB/s"), tr("GB/s"), tr("TB/s") }, // SPEED
{ tr("B"), tr("kB"), tr("MB"), tr("GB"), tr("TB") }, // SIZE
{ tr("B"), tr("KiB"), tr("MiB"), tr("GiB"), tr("TiB") } // MEM
} }
{
namespace Values = libtransmission::Values;
auto const& speed = UnitStrings[SPEED];
Values::Config::Speed = { Values::Config::Base::Kilo, "B"sv,
speed[KB].toStdString(), speed[MB].toStdString(),
speed[GB].toStdString(), speed[TB].toStdString() };
auto const& size = UnitStrings[SIZE];
tr_formatter_size_init(
SizeBase,
size[KB].toUtf8().constData(),
size[MB].toUtf8().constData(),
size[GB].toUtf8().constData(),
size[TB].toUtf8().constData());
auto const& mem = UnitStrings[MEM];
tr_formatter_mem_init(
MemBase,
mem[KB].toUtf8().constData(),
mem[MB].toUtf8().constData(),
mem[GB].toUtf8().constData(),
mem[TB].toUtf8().constData());
}
QString Formatter::unitStr(Type t, Size s) const
{
return UnitStrings[t][s];
}
QString Formatter::memToString(int64_t bytes) const
{ {
if (bytes < 0) if (bytes < 0)
{ {
@ -74,7 +29,7 @@ QString Formatter::memToString(int64_t bytes) const
return QString::fromStdString(Memory{ bytes, Memory::Units::Bytes }.to_string()); return QString::fromStdString(Memory{ bytes, Memory::Units::Bytes }.to_string());
} }
QString Formatter::sizeToString(uint64_t bytes) const QString Formatter::storage_to_string(uint64_t const bytes)
{ {
if (bytes == 0) if (bytes == 0)
{ {
@ -84,17 +39,17 @@ QString Formatter::sizeToString(uint64_t bytes) const
return QString::fromStdString(Storage{ bytes, Storage::Units::Bytes }.to_string()); return QString::fromStdString(Storage{ bytes, Storage::Units::Bytes }.to_string());
} }
QString Formatter::sizeToString(int64_t bytes) const QString Formatter::storage_to_string(int64_t const bytes)
{ {
if (bytes < 0) if (bytes < 0)
{ {
return tr("Unknown"); return tr("Unknown");
} }
return Formatter::sizeToString(static_cast<uint64_t>(bytes)); return storage_to_string(static_cast<uint64_t>(bytes));
} }
QString Formatter::timeToString(int seconds) const QString Formatter::time_to_string(int seconds)
{ {
seconds = std::max(seconds, 0); seconds = std::max(seconds, 0);

View File

@ -20,52 +20,24 @@ class Formatter
Q_DECLARE_TR_FUNCTIONS(Formatter) Q_DECLARE_TR_FUNCTIONS(Formatter)
public: public:
enum Size Formatter() = delete;
{
B,
KB,
MB,
GB,
TB,
NUM_SIZES [[nodiscard]] static QString memory_to_string(int64_t bytes);
};
enum Type [[nodiscard]] static auto percent_to_string(double x)
{
SPEED,
SIZE,
MEM,
NUM_TYPES
};
static constexpr int SizeBase = 1000;
static constexpr int MemBase = 1024;
[[nodiscard]] static Formatter& get();
[[nodiscard]] QString memToString(int64_t bytes) const;
[[nodiscard]] QString sizeToString(int64_t bytes) const;
[[nodiscard]] QString sizeToString(uint64_t bytes) const;
[[nodiscard]] QString timeToString(int seconds) const;
[[nodiscard]] QString unitStr(Type t, Size s) const;
[[nodiscard]] auto percentToString(double x) const
{ {
return QString::fromStdString(tr_strpercent(x)); return QString::fromStdString(tr_strpercent(x));
} }
[[nodiscard]] auto ratioToString(double ratio) const [[nodiscard]] static auto ratio_to_string(double ratio)
{ {
static auto constexpr InfinitySymbol = "\xE2\x88\x9E"; static auto constexpr InfinitySymbol = "\xE2\x88\x9E";
return QString::fromStdString(tr_strratio(ratio, InfinitySymbol)); return QString::fromStdString(tr_strratio(ratio, InfinitySymbol));
} }
protected: [[nodiscard]] static QString storage_to_string(int64_t bytes);
Formatter(); [[nodiscard]] static QString storage_to_string(uint64_t bytes);
private: [[nodiscard]] static QString time_to_string(int seconds);
std::array<std::array<QString, Formatter::NUM_SIZES>, Formatter::NUM_TYPES> const UnitStrings;
}; };

View File

@ -78,7 +78,7 @@ void FreeSpaceLabel::onTimer()
// update the label // update the label
if (auto const bytes = dictFind<int64_t>(r.args.get(), TR_KEY_size_bytes); bytes && *bytes > 1) if (auto const bytes = dictFind<int64_t>(r.args.get(), TR_KEY_size_bytes); bytes && *bytes > 1)
{ {
setText(tr("%1 free").arg(Formatter::get().sizeToString(*bytes))); setText(tr("%1 free").arg(Formatter::storage_to_string(*bytes)));
} }
else else
{ {

View File

@ -446,7 +446,7 @@ QMenu* MainWindow::createOptionsMenu()
action_group->addAction(off_action); action_group->addAction(off_action);
connect(off_action, &QAction::triggered, this, qOverload<bool>(&MainWindow::onSetPrefs)); connect(off_action, &QAction::triggered, this, qOverload<bool>(&MainWindow::onSetPrefs));
on_action = menu->addAction(tr("Stop at Ratio (%1)").arg(Formatter::get().ratioToString(current_value))); on_action = menu->addAction(tr("Stop at Ratio (%1)").arg(Formatter::ratio_to_string(current_value)));
on_action->setCheckable(true); on_action->setCheckable(true);
on_action->setProperty(PrefVariantsKey, QVariantList{ pref, current_value, enabled_pref, true }); on_action->setProperty(PrefVariantsKey, QVariantList{ pref, current_value, enabled_pref, true });
action_group->addAction(on_action); action_group->addAction(on_action);
@ -456,7 +456,7 @@ QMenu* MainWindow::createOptionsMenu()
for (double const i : StockRatios) for (double const i : StockRatios)
{ {
QAction* action = menu->addAction(Formatter::get().ratioToString(i)); QAction* action = menu->addAction(Formatter::ratio_to_string(i));
action->setProperty(PrefVariantsKey, QVariantList{ pref, i, enabled_pref, true }); action->setProperty(PrefVariantsKey, QVariantList{ pref, i, enabled_pref, true });
connect(action, &QAction::triggered, this, qOverload<>(&MainWindow::onSetPrefs)); connect(action, &QAction::triggered, this, qOverload<>(&MainWindow::onSetPrefs));
} }
@ -824,7 +824,6 @@ void MainWindow::refreshTrayIcon(TransferStats const& stats)
void MainWindow::refreshStatusBar(TransferStats const& stats) void MainWindow::refreshStatusBar(TransferStats const& stats)
{ {
auto const& fmt = Formatter::get();
ui_.uploadSpeedLabel->setText(stats.speed_up.to_upload_qstring()); ui_.uploadSpeedLabel->setText(stats.speed_up.to_upload_qstring());
ui_.uploadSpeedLabel->setVisible(stats.peers_sending || stats.peers_receiving); ui_.uploadSpeedLabel->setVisible(stats.peers_sending || stats.peers_receiving);
ui_.downloadSpeedLabel->setText(stats.speed_down.to_download_qstring()); ui_.downloadSpeedLabel->setText(stats.speed_down.to_download_qstring());
@ -837,22 +836,26 @@ void MainWindow::refreshStatusBar(TransferStats const& stats)
if (mode == session_ratio_stats_mode_name_) if (mode == session_ratio_stats_mode_name_)
{ {
str = tr("Ratio: %1").arg(fmt.ratioToString(session_.getStats().ratio)); str = tr("Ratio: %1").arg(Formatter::ratio_to_string(session_.getStats().ratio));
} }
else if (mode == session_transfer_stats_mode_name_) else if (mode == session_transfer_stats_mode_name_)
{ {
auto const& st = session_.getStats(); auto const& st = session_.getStats();
str = tr("Down: %1, Up: %2").arg(fmt.sizeToString(st.downloadedBytes)).arg(fmt.sizeToString(st.uploadedBytes)); str = tr("Down: %1, Up: %2")
.arg(Formatter::storage_to_string(st.downloadedBytes))
.arg(Formatter::storage_to_string(st.uploadedBytes));
} }
else if (mode == total_transfer_stats_mode_name_) else if (mode == total_transfer_stats_mode_name_)
{ {
auto const& st = session_.getCumulativeStats(); auto const& st = session_.getCumulativeStats();
str = tr("Down: %1, Up: %2").arg(fmt.sizeToString(st.downloadedBytes)).arg(fmt.sizeToString(st.uploadedBytes)); str = tr("Down: %1, Up: %2")
.arg(Formatter::storage_to_string(st.downloadedBytes))
.arg(Formatter::storage_to_string(st.uploadedBytes));
} }
else // default is "total-ratio" else // default is "total-ratio"
{ {
assert(mode == total_ratio_stats_mode_name_); assert(mode == total_ratio_stats_mode_name_);
str = tr("Ratio: %1").arg(fmt.ratioToString(session_.getCumulativeStats().ratio)); str = tr("Ratio: %1").arg(Formatter::ratio_to_string(session_.getCumulativeStats().ratio));
} }
ui_.statsLabel->setText(str); ui_.statsLabel->setText(str);
@ -1188,7 +1191,7 @@ void MainWindow::refreshPref(int key)
break; break;
case Prefs::RATIO: case Prefs::RATIO:
ratio_on_action_->setText(tr("Stop at Ratio (%1)").arg(Formatter::get().ratioToString(prefs_.get<double>(key)))); ratio_on_action_->setText(tr("Stop at Ratio (%1)").arg(Formatter::ratio_to_string(prefs_.get<double>(key))));
break; break;
case Prefs::FILTERBAR: case Prefs::FILTERBAR:
@ -1241,7 +1244,7 @@ void MainWindow::refreshPref(int key)
b = prefs_.getBool(Prefs::ALT_SPEED_LIMIT_ENABLED); b = prefs_.getBool(Prefs::ALT_SPEED_LIMIT_ENABLED);
alt_speed_action_->setChecked(b); alt_speed_action_->setChecked(b);
ui_.altSpeedButton->setChecked(b); ui_.altSpeedButton->setChecked(b);
QString const fmt = b ? tr("Click to disable Temporary Speed Limits\n (%1 down, %2 up)") : auto const fmt = b ? tr("Click to disable Temporary Speed Limits\n (%1 down, %2 up)") :
tr("Click to enable Temporary Speed Limits\n (%1 down, %2 up)"); tr("Click to enable Temporary Speed Limits\n (%1 down, %2 up)");
auto const d = Speed{ prefs_.get<unsigned int>(Prefs::ALT_SPEED_LIMIT_DOWN), Speed::Units::KByps }; auto const d = Speed{ prefs_.get<unsigned int>(Prefs::ALT_SPEED_LIMIT_DOWN), Speed::Units::KByps };
auto const u = Speed{ prefs_.get<unsigned int>(Prefs::ALT_SPEED_LIMIT_UP), Speed::Units::KByps }; auto const u = Speed{ prefs_.get<unsigned int>(Prefs::ALT_SPEED_LIMIT_UP), Speed::Units::KByps };
@ -1495,7 +1498,7 @@ void MainWindow::updateNetworkIcon()
} }
else if (seconds_since_last_read < 120) else if (seconds_since_last_read < 120)
{ {
tip = tr("%1 last responded %2 ago").arg(url).arg(Formatter::get().timeToString(seconds_since_last_read)); tip = tr("%1 last responded %2 ago").arg(url).arg(Formatter::time_to_string(seconds_since_last_read));
} }
else else
{ {

View File

@ -309,10 +309,10 @@ void MakeDialog::updatePiecesLabel()
auto const files = tr("%Ln File(s)", nullptr, builder_->file_count()); auto const files = tr("%Ln File(s)", nullptr, builder_->file_count());
auto const pieces = tr("%Ln Piece(s)", nullptr, builder_->piece_count()); auto const pieces = tr("%Ln Piece(s)", nullptr, builder_->piece_count());
text = tr("%1 in %2; %3 @ %4") text = tr("%1 in %2; %3 @ %4")
.arg(Formatter::get().sizeToString(builder_->total_size())) .arg(Formatter::storage_to_string(builder_->total_size()))
.arg(files) .arg(files)
.arg(pieces) .arg(pieces)
.arg(Formatter::get().memToString(static_cast<uint64_t>(builder_->piece_size()))); .arg(Formatter::memory_to_string(static_cast<uint64_t>(builder_->piece_size())));
ui_.pieceSizeSlider->setEnabled(true); ui_.pieceSizeSlider->setEnabled(true);
} }

View File

@ -36,9 +36,7 @@
#include "Session.h" #include "Session.h"
#include "Utils.h" #include "Utils.h"
/*** // ---
****
***/
namespace namespace
{ {
@ -370,9 +368,9 @@ void PrefsDialog::altSpeedDaysEdited(int i)
void PrefsDialog::initSpeedTab() void PrefsDialog::initSpeedTab()
{ {
QString const speed_unit_str = Formatter::get().unitStr(Formatter::get().SPEED, Formatter::get().KB); auto const suffix = QStringLiteral(" %1").arg(Speed::display_name(Speed::Units::KByps));
auto const suffix = QStringLiteral(" %1").arg(speed_unit_str);
QLocale const locale; auto const locale = QLocale{};
ui_.uploadSpeedLimitSpin->setSuffix(suffix); ui_.uploadSpeedLimitSpin->setSuffix(suffix);
ui_.downloadSpeedLimitSpin->setSuffix(suffix); ui_.downloadSpeedLimitSpin->setSuffix(suffix);

View File

@ -29,11 +29,6 @@ public:
{ {
} }
[[nodiscard]] auto constexpr is_zero() const noexcept
{
return base_quantity() == 0U;
}
[[nodiscard]] auto to_qstring() const noexcept [[nodiscard]] auto to_qstring() const noexcept
{ {
return QString::fromStdString(to_string()); return QString::fromStdString(to_string());
@ -55,4 +50,10 @@ public:
{ {
return Speed{ base_quantity() + other.base_quantity(), Speed::Units::Byps }; return Speed{ base_quantity() + other.base_quantity(), Speed::Units::Byps };
} }
[[nodiscard]] static auto display_name(Speed::Units const units)
{
auto const speed_unit_sv = Speed::units().display_name(units);
return QString::fromUtf8(std::data(speed_unit_sv), std::size(speed_unit_sv));
}
}; };

View File

@ -50,15 +50,15 @@ void StatsDialog::updateStats()
tr_session_stats const& current(session_.getStats()); tr_session_stats const& current(session_.getStats());
tr_session_stats const& total(session_.getCumulativeStats()); tr_session_stats const& total(session_.getCumulativeStats());
ui_.currentUploadedValueLabel->setText(Formatter::get().sizeToString(current.uploadedBytes)); ui_.currentUploadedValueLabel->setText(Formatter::storage_to_string(current.uploadedBytes));
ui_.currentDownloadedValueLabel->setText(Formatter::get().sizeToString(current.downloadedBytes)); ui_.currentDownloadedValueLabel->setText(Formatter::storage_to_string(current.downloadedBytes));
ui_.currentRatioValueLabel->setText(Formatter::get().ratioToString(current.ratio)); ui_.currentRatioValueLabel->setText(Formatter::ratio_to_string(current.ratio));
ui_.currentDurationValueLabel->setText(Formatter::get().timeToString(current.secondsActive)); ui_.currentDurationValueLabel->setText(Formatter::time_to_string(current.secondsActive));
ui_.totalUploadedValueLabel->setText(Formatter::get().sizeToString(total.uploadedBytes)); ui_.totalUploadedValueLabel->setText(Formatter::storage_to_string(total.uploadedBytes));
ui_.totalDownloadedValueLabel->setText(Formatter::get().sizeToString(total.downloadedBytes)); ui_.totalDownloadedValueLabel->setText(Formatter::storage_to_string(total.downloadedBytes));
ui_.totalRatioValueLabel->setText(Formatter::get().ratioToString(total.ratio)); ui_.totalRatioValueLabel->setText(Formatter::ratio_to_string(total.ratio));
ui_.totalDurationValueLabel->setText(Formatter::get().timeToString(total.secondsActive)); ui_.totalDurationValueLabel->setText(Formatter::time_to_string(total.secondsActive));
ui_.startCountLabel->setText(tr("Started %Ln time(s)", nullptr, total.sessionCount)); ui_.startCountLabel->setText(tr("Started %Ln time(s)", nullptr, total.sessionCount));
} }

View File

@ -172,7 +172,7 @@ QString TorrentDelegate::progressString(Torrent const& tor)
//: First part of torrent progress string, //: First part of torrent progress string,
//: %1 is the percentage of torrent metadata downloaded //: %1 is the percentage of torrent metadata downloaded
str = tr("Magnetized transfer - retrieving metadata (%1%)") str = tr("Magnetized transfer - retrieving metadata (%1%)")
.arg(Formatter::get().percentToString(tor.metadataPercentDone() * 100.0)); .arg(Formatter::percent_to_string(tor.metadataPercentDone() * 100.0));
} }
else if (!is_done) // downloading else if (!is_done) // downloading
{ {
@ -181,9 +181,9 @@ QString TorrentDelegate::progressString(Torrent const& tor)
//: %2 is how much we'll have when done, //: %2 is how much we'll have when done,
//: %3 is a percentage of the two //: %3 is a percentage of the two
str = tr("%1 of %2 (%3%)") str = tr("%1 of %2 (%3%)")
.arg(Formatter::get().sizeToString(have_total)) .arg(Formatter::storage_to_string(have_total))
.arg(Formatter::get().sizeToString(tor.sizeWhenDone())) .arg(Formatter::storage_to_string(tor.sizeWhenDone()))
.arg(Formatter::get().percentToString(tor.percentDone() * 100.0)); .arg(Formatter::percent_to_string(tor.percentDone() * 100.0));
} }
else if (!is_seed) // partial seed else if (!is_seed) // partial seed
{ {
@ -197,12 +197,12 @@ QString TorrentDelegate::progressString(Torrent const& tor)
//: %5 is our upload-to-download ratio, //: %5 is our upload-to-download ratio,
//: %6 is the ratio we want to reach before we stop uploading //: %6 is the ratio we want to reach before we stop uploading
str = tr("%1 of %2 (%3%), uploaded %4 (Ratio: %5 Goal: %6)") str = tr("%1 of %2 (%3%), uploaded %4 (Ratio: %5 Goal: %6)")
.arg(Formatter::get().sizeToString(have_total)) .arg(Formatter::storage_to_string(have_total))
.arg(Formatter::get().sizeToString(tor.totalSize())) .arg(Formatter::storage_to_string(tor.totalSize()))
.arg(Formatter::get().percentToString(tor.percentComplete() * 100.0)) .arg(Formatter::percent_to_string(tor.percentComplete() * 100.0))
.arg(Formatter::get().sizeToString(tor.uploadedEver())) .arg(Formatter::storage_to_string(tor.uploadedEver()))
.arg(Formatter::get().ratioToString(tor.ratio())) .arg(Formatter::ratio_to_string(tor.ratio()))
.arg(Formatter::get().ratioToString(*seed_ratio_limit)); .arg(Formatter::ratio_to_string(*seed_ratio_limit));
} }
else else
{ {
@ -213,11 +213,11 @@ QString TorrentDelegate::progressString(Torrent const& tor)
//: %4 is how much we've uploaded, //: %4 is how much we've uploaded,
//: %5 is our upload-to-download ratio //: %5 is our upload-to-download ratio
str = tr("%1 of %2 (%3%), uploaded %4 (Ratio: %5)") str = tr("%1 of %2 (%3%), uploaded %4 (Ratio: %5)")
.arg(Formatter::get().sizeToString(have_total)) .arg(Formatter::storage_to_string(have_total))
.arg(Formatter::get().sizeToString(tor.totalSize())) .arg(Formatter::storage_to_string(tor.totalSize()))
.arg(Formatter::get().percentToString(tor.percentComplete() * 100.0)) .arg(Formatter::percent_to_string(tor.percentComplete() * 100.0))
.arg(Formatter::get().sizeToString(tor.uploadedEver())) .arg(Formatter::storage_to_string(tor.uploadedEver()))
.arg(Formatter::get().ratioToString(tor.ratio())); .arg(Formatter::ratio_to_string(tor.ratio()));
} }
} }
else // seeding else // seeding
@ -230,10 +230,10 @@ QString TorrentDelegate::progressString(Torrent const& tor)
//: %3 is our upload-to-download ratio, //: %3 is our upload-to-download ratio,
//: %4 is the ratio we want to reach before we stop uploading //: %4 is the ratio we want to reach before we stop uploading
str = tr("%1, uploaded %2 (Ratio: %3 Goal: %4)") str = tr("%1, uploaded %2 (Ratio: %3 Goal: %4)")
.arg(Formatter::get().sizeToString(have_total)) .arg(Formatter::storage_to_string(have_total))
.arg(Formatter::get().sizeToString(tor.uploadedEver())) .arg(Formatter::storage_to_string(tor.uploadedEver()))
.arg(Formatter::get().ratioToString(tor.ratio())) .arg(Formatter::ratio_to_string(tor.ratio()))
.arg(Formatter::get().ratioToString(*seed_ratio_limit)); .arg(Formatter::ratio_to_string(*seed_ratio_limit));
} }
else // seeding w/o a ratio else // seeding w/o a ratio
{ {
@ -242,9 +242,9 @@ QString TorrentDelegate::progressString(Torrent const& tor)
//: %2 is how much we've uploaded, //: %2 is how much we've uploaded,
//: %3 is our upload-to-download ratio //: %3 is our upload-to-download ratio
str = tr("%1, uploaded %2 (Ratio: %3)") str = tr("%1, uploaded %2 (Ratio: %3)")
.arg(Formatter::get().sizeToString(have_total)) .arg(Formatter::storage_to_string(have_total))
.arg(Formatter::get().sizeToString(tor.uploadedEver())) .arg(Formatter::storage_to_string(tor.uploadedEver()))
.arg(Formatter::get().ratioToString(tor.ratio())); .arg(Formatter::ratio_to_string(tor.ratio()));
} }
} }
@ -256,7 +256,7 @@ QString TorrentDelegate::progressString(Torrent const& tor)
//: Second (optional) part of torrent progress string, //: Second (optional) part of torrent progress string,
//: %1 is duration, //: %1 is duration,
//: notice that leading space (before the dash) is included here //: notice that leading space (before the dash) is included here
str += tr(" - %1 left").arg(Formatter::get().timeToString(tor.getETA())); str += tr(" - %1 left").arg(Formatter::time_to_string(tor.getETA()));
} }
else else
{ {
@ -295,13 +295,12 @@ QString TorrentDelegate::shortStatusString(Torrent const& tor)
switch (tor.getActivity()) switch (tor.getActivity())
{ {
case TR_STATUS_CHECK: case TR_STATUS_CHECK:
str = tr("Verifying local data (%1% tested)").arg(Formatter::get().percentToString(tor.getVerifyProgress() * 100.0)); str = tr("Verifying local data (%1% tested)").arg(Formatter::percent_to_string(tor.getVerifyProgress() * 100.0));
break; break;
case TR_STATUS_DOWNLOAD: case TR_STATUS_DOWNLOAD:
case TR_STATUS_SEED: case TR_STATUS_SEED:
str = shortTransferString(tor) + QStringLiteral(" ") + str = shortTransferString(tor) + QStringLiteral(" ") + tr("Ratio: %1").arg(Formatter::ratio_to_string(tor.ratio()));
tr("Ratio: %1").arg(Formatter::get().ratioToString(tor.ratio()));
break; break;
default: default:
@ -336,7 +335,7 @@ QString TorrentDelegate::statusString(Torrent const& tor)
if (!tor.hasMetadata()) if (!tor.hasMetadata())
{ {
str = tr("Downloading metadata from %Ln peer(s) (%1% done)", nullptr, tor.peersWeAreDownloadingFrom()) str = tr("Downloading metadata from %Ln peer(s) (%1% done)", nullptr, tor.peersWeAreDownloadingFrom())
.arg(Formatter::get().percentToString(100.0 * tor.metadataPercentDone())); .arg(Formatter::percent_to_string(100.0 * tor.metadataPercentDone()));
} }
else else
{ {

View File

@ -24,7 +24,6 @@
namespace namespace
{ {
auto constexpr Spacing = int{ 6 }; auto constexpr Spacing = int{ 6 };
auto constexpr Margin = QSize{ 10, 10 }; auto constexpr Margin = QSize{ 10, 10 };
@ -158,17 +157,15 @@ void TrackerDelegate::setShowMore(bool b)
namespace namespace
{ {
QString timeToRoundedString(int seconds)
QString timeToStringRounded(int seconds)
{ {
if (seconds > 60) if (seconds > 60)
{ {
seconds -= seconds % 60; seconds -= seconds % 60;
} }
return Formatter::get().timeToString(seconds); return Formatter::time_to_string(seconds);
} }
} // namespace } // namespace
QString TrackerDelegate::getText(TrackerInfo const& inf) const QString TrackerDelegate::getText(TrackerInfo const& inf) const
@ -184,11 +181,11 @@ QString TrackerDelegate::getText(TrackerInfo const& inf) const
auto const now = time(nullptr); auto const now = time(nullptr);
auto const time_until = [&now](auto t) auto const time_until = [&now](auto t)
{ {
return timeToStringRounded(static_cast<int>(t - now)); return timeToRoundedString(static_cast<int>(t - now));
}; };
auto const time_since = [&now](auto t) auto const time_since = [&now](auto t)
{ {
return timeToStringRounded(static_cast<int>(now - t)); return timeToRoundedString(static_cast<int>(now - t));
}; };
// hostname // hostname

View File

@ -50,11 +50,14 @@ TEST_F(ValuesTest, toString)
EXPECT_EQ("999.2 kB/s", val.to_string()); EXPECT_EQ("999.2 kB/s", val.to_string());
} }
TEST_F(ValuesTest, valueHonorsFormatterInit) TEST_F(ValuesTest, isZero)
{ {
tr_formatter_speed_init(1024, "KayBeePerEss", "EmmBeePerEss", "GeeBeePerEss", "TeeBeePerEss"); auto val = Speed{};
EXPECT_TRUE(val.is_zero());
auto const val = Speed{ 1, Speed::Units::MByps }; val = Speed{ 0, Speed::Units::Byps };
EXPECT_EQ("1 EmmBeePerEss", val.to_string()); EXPECT_TRUE(val.is_zero());
EXPECT_EQ(1048576U, val.base_quantity());
val = Speed{ 1, Speed::Units::Byps };
EXPECT_FALSE(val.is_zero());
} }