Fix issues reported by clang-tidy `cppcoreguidelines` checks (GTK client) (#4158)
* Fix `cppcoreguidelines-pro-type-cstyle-cast` clang-tidy issues * Fix `cppcoreguidelines-pro-type-member-init` clang-tidy issues * Fix `cppcoreguidelines-prefer-member-initializer` clang-tidy issues * Introduce `PageBase` for `PrefsDialog` pages This is in preparation for next PR fixing `Glib::Timer` memory management. * Fix `cppcoreguidelines-owning-memory` clang-tidy issues * Fix `cppcoreguidelines-pro-bounds-array-to-pointer-decay` clang-tidy issues * Fix `cppcoreguidelines-special-member-functions` clang-tidy issues * Fix `cppcoreguidelines-init-variables` clang-tidy issues * Fix `cppcoreguidelines-macro-usage` clang-tidy issues * Fix `cppcoreguidelines-pro-bounds-constant-array-index` clang-tidy issues * Fix `cppcoreguidelines-non-private-member-variables-in-classes` clang-tidy issues * Fix `cppcoreguidelines-pro-type-vararg` clang-tidy issues * Fix `cppcoreguidelines-pro-bounds-pointer-arithmetic` clang-tidy issue * Fix `cppcoreguidelines-pro-type-reinterpret-cast` clang-tidy issues * Fix `cppcoreguidelines-pro-type-static-cast-downcast` clang-tidy issues * Extend clang-tidy configuration Enable all `cppcoreguidelines` checks except for three (`avoid-magic- numbers`, `avoid-non-const-global-variables`, `narrowing-conversions`) which require [more] extensive refactoring and were left for later.
This commit is contained in:
parent
0ecf084e0f
commit
49ce12ce38
|
@ -1,6 +1,10 @@
|
|||
---
|
||||
Checks: >
|
||||
-*,
|
||||
cppcoreguidelines-*,
|
||||
-cppcoreguidelines-avoid-magic-numbers,
|
||||
-cppcoreguidelines-avoid-non-const-global-variables,
|
||||
-cppcoreguidelines-narrowing-conversions,
|
||||
modernize-*,
|
||||
-modernize-use-trailing-return-type,
|
||||
readability-*,
|
||||
|
|
|
@ -87,6 +87,7 @@ class Application::Impl
|
|||
{
|
||||
public:
|
||||
Impl(Application& app, std::string const& config_dir, bool start_paused, bool is_iconified);
|
||||
~Impl() = default;
|
||||
|
||||
TR_DISABLE_COPY_MOVE(Impl)
|
||||
|
||||
|
@ -293,10 +294,9 @@ bool Application::Impl::refresh_actions()
|
|||
size_t const total = core_->get_torrent_count();
|
||||
size_t const active = core_->get_active_torrent_count();
|
||||
auto const torrent_count = core_->get_model()->children().size();
|
||||
bool has_selection;
|
||||
|
||||
auto const sel_counts = get_selected_torrent_counts();
|
||||
has_selection = sel_counts.total_count > 0;
|
||||
bool const has_selection = sel_counts.total_count > 0;
|
||||
|
||||
gtr_action_set_sensitive("select-all", torrent_count != 0);
|
||||
gtr_action_set_sensitive("deselect-all", torrent_count != 0);
|
||||
|
@ -366,12 +366,11 @@ void register_magnet_link_handler()
|
|||
}
|
||||
catch (Gio::Error const& e)
|
||||
{
|
||||
auto const msg = fmt::format(
|
||||
gtr_warning(fmt::format(
|
||||
_("Couldn't register Transmission as a {content_type} handler: {error} ({error_code})"),
|
||||
fmt::arg("content_type", content_type),
|
||||
fmt::arg("error", e.what()),
|
||||
fmt::arg("error_code", e.code()));
|
||||
g_warning("%s", msg.c_str());
|
||||
fmt::arg("error_code", e.code())));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -399,15 +398,15 @@ void Application::Impl::on_main_window_size_allocated()
|
|||
if (!is_maximized)
|
||||
{
|
||||
#if !GTKMM_CHECK_VERSION(4, 0, 0)
|
||||
int x;
|
||||
int y;
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
wind_->get_position(x, y);
|
||||
gtr_pref_int_set(TR_KEY_main_window_x, x);
|
||||
gtr_pref_int_set(TR_KEY_main_window_y, y);
|
||||
#endif
|
||||
|
||||
int w;
|
||||
int h;
|
||||
int w = 0;
|
||||
int h = 0;
|
||||
#if GTKMM_CHECK_VERSION(4, 0, 0)
|
||||
wind_->get_default_size(w, h);
|
||||
#else
|
||||
|
@ -449,9 +448,9 @@ bool Application::Impl::on_rpc_changed_idle(tr_rpc_callback_type type, tr_torren
|
|||
case TR_RPC_SESSION_CHANGED:
|
||||
{
|
||||
tr_variant tmp;
|
||||
tr_variant* newval;
|
||||
tr_variant* newval = nullptr;
|
||||
tr_variant* oldvals = gtr_pref_get_all();
|
||||
tr_quark key;
|
||||
tr_quark key = TR_KEY_NONE;
|
||||
std::vector<tr_quark> changed_keys;
|
||||
auto const* const session = core_->get_session();
|
||||
tr_variantInitDict(&tmp, 100);
|
||||
|
@ -459,13 +458,9 @@ bool Application::Impl::on_rpc_changed_idle(tr_rpc_callback_type type, tr_torren
|
|||
|
||||
for (int i = 0; tr_variantDictChild(&tmp, i, &key, &newval); ++i)
|
||||
{
|
||||
bool changed;
|
||||
bool changed = true;
|
||||
|
||||
if (tr_variant const* oldval = tr_variantDictFind(oldvals, key); oldval == nullptr)
|
||||
{
|
||||
changed = true;
|
||||
}
|
||||
else
|
||||
if (tr_variant const* oldval = tr_variantDictFind(oldvals, key); oldval != nullptr)
|
||||
{
|
||||
auto const a = tr_variantToStr(oldval, TR_VARIANT_FMT_BENC);
|
||||
auto const b = tr_variantToStr(newval, TR_VARIANT_FMT_BENC);
|
||||
|
@ -529,7 +524,7 @@ namespace
|
|||
|
||||
gboolean signal_handler(gpointer user_data)
|
||||
{
|
||||
g_message(_("Got termination signal, trying to shut down cleanly. Do it again if it gets stuck."));
|
||||
gtr_message(_("Got termination signal, trying to shut down cleanly. Do it again if it gets stuck."));
|
||||
gtr_actions_handler("quit", user_data);
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
@ -567,7 +562,7 @@ void Application::Impl::on_startup()
|
|||
std::ignore = FilterBar();
|
||||
std::ignore = PathButton();
|
||||
|
||||
tr_session* session;
|
||||
tr_session* session = nullptr;
|
||||
|
||||
#ifdef G_OS_UNIX
|
||||
g_unix_signal_add(SIGINT, &signal_handler, this);
|
||||
|
@ -976,8 +971,7 @@ void Application::Impl::on_app_exit()
|
|||
refresh_actions_tag_.disconnect();
|
||||
|
||||
#if !GTKMM_CHECK_VERSION(4, 0, 0)
|
||||
auto* c = static_cast<Gtk::Container*>(wind_.get());
|
||||
c->remove(*static_cast<Gtk::Bin*>(c)->get_child());
|
||||
wind_->remove();
|
||||
#endif
|
||||
|
||||
wind_->set_show_menubar(false);
|
||||
|
@ -989,7 +983,7 @@ void Application::Impl::on_app_exit()
|
|||
#if GTKMM_CHECK_VERSION(4, 0, 0)
|
||||
wind_->set_child(*p);
|
||||
#else
|
||||
c->add(*p);
|
||||
wind_->add(*p);
|
||||
#endif
|
||||
|
||||
auto* icon = Gtk::make_managed<Gtk::Image>();
|
||||
|
@ -1427,15 +1421,13 @@ void Application::Impl::show_about_dialog()
|
|||
bool Application::Impl::call_rpc_for_selected_torrents(std::string const& method)
|
||||
{
|
||||
tr_variant top;
|
||||
tr_variant* args;
|
||||
tr_variant* ids;
|
||||
bool invoked = false;
|
||||
auto* session = core_->get_session();
|
||||
|
||||
tr_variantInitDict(&top, 2);
|
||||
tr_variantDictAddStrView(&top, TR_KEY_method, method);
|
||||
args = tr_variantDictAddDict(&top, TR_KEY_arguments, 1);
|
||||
ids = tr_variantDictAddList(args, TR_KEY_ids, 0);
|
||||
auto* const args = tr_variantDictAddDict(&top, TR_KEY_arguments, 1);
|
||||
auto* const ids = tr_variantDictAddList(args, TR_KEY_ids, 0);
|
||||
sel_->selected_foreach(
|
||||
[ids](auto const& /*path*/, auto const& iter)
|
||||
{
|
||||
|
@ -1667,7 +1659,7 @@ void Application::Impl::actions_handler(Glib::ustring const& action_name)
|
|||
}
|
||||
else
|
||||
{
|
||||
g_error("%s", fmt::format("Unhandled action: {}", action_name).c_str());
|
||||
gtr_error(fmt::format("Unhandled action: {}", action_name));
|
||||
}
|
||||
|
||||
if (changed)
|
||||
|
|
|
@ -1172,16 +1172,19 @@ void initPeerRow(
|
|||
}
|
||||
|
||||
auto peer_addr4 = in_addr();
|
||||
auto const collated_name = inet_pton(AF_INET, peer->addr, &peer_addr4) != 1 ?
|
||||
peer->addr :
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
|
||||
auto const* const peer_addr4_octets = reinterpret_cast<uint8_t const*>(&peer_addr4.s_addr);
|
||||
auto const collated_name = inet_pton(AF_INET, std::data(peer->addr), &peer_addr4) != 1 ?
|
||||
std::data(peer->addr) :
|
||||
fmt::format(
|
||||
"{:03}",
|
||||
fmt::join(
|
||||
reinterpret_cast<uint8_t const*>(&peer_addr4.s_addr),
|
||||
reinterpret_cast<uint8_t const*>(&peer_addr4.s_addr) + sizeof(peer_addr4.s_addr),
|
||||
peer_addr4_octets,
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
|
||||
peer_addr4_octets + sizeof(peer_addr4.s_addr), // TODO(C++20): Use std::span
|
||||
"."));
|
||||
|
||||
(*iter)[peer_cols.address] = peer->addr;
|
||||
(*iter)[peer_cols.address] = std::data(peer->addr);
|
||||
(*iter)[peer_cols.address_collated] = collated_name;
|
||||
(*iter)[peer_cols.client] = client;
|
||||
(*iter)[peer_cols.encryption_stock_id] = peer->isEncrypted ? "lock" : "";
|
||||
|
@ -1251,7 +1254,7 @@ void refreshPeerRow(Gtk::TreeModel::iterator const& iter, tr_peer_stat const* pe
|
|||
(*iter)[peer_cols.download_rate_string] = down_speed;
|
||||
(*iter)[peer_cols.upload_rate_double] = peer->rateToPeer_KBps;
|
||||
(*iter)[peer_cols.upload_rate_string] = up_speed;
|
||||
(*iter)[peer_cols.flags] = peer->flagStr;
|
||||
(*iter)[peer_cols.flags] = std::data(peer->flagStr);
|
||||
(*iter)[peer_cols.was_updated] = true;
|
||||
(*iter)[peer_cols.blocks_downloaded_count_int] = (int)peer->blocksToClient;
|
||||
(*iter)[peer_cols.blocks_downloaded_count_string] = blocks_to_client;
|
||||
|
@ -1533,7 +1536,7 @@ namespace
|
|||
void setPeerViewColumns(Gtk::TreeView* peer_view)
|
||||
{
|
||||
std::vector<Gtk::TreeModelColumnBase const*> view_columns;
|
||||
Gtk::TreeViewColumn* c;
|
||||
Gtk::TreeViewColumn* c = nullptr;
|
||||
bool const more = gtr_pref_flag_get(TR_KEY_show_extra_peer_details);
|
||||
|
||||
view_columns.push_back(&peer_cols.encryption_stock_id);
|
||||
|
@ -1777,7 +1780,7 @@ std::array<std::string_view, 3> const text_dir_mark = { ""sv, "\u200E"sv, "\u200
|
|||
|
||||
void appendAnnounceInfo(tr_tracker_view const& tracker, time_t const now, Gtk::TextDirection direction, std::ostream& gstr)
|
||||
{
|
||||
auto const dir_mark = text_dir_mark[static_cast<int>(direction)];
|
||||
auto const dir_mark = text_dir_mark.at(static_cast<int>(direction));
|
||||
|
||||
if (tracker.hasAnnounced && tracker.announceState != TR_TRACKER_INACTIVE)
|
||||
{
|
||||
|
@ -1813,7 +1816,7 @@ void appendAnnounceInfo(tr_tracker_view const& tracker, time_t const now, Gtk::T
|
|||
// {markup_begin} and {markup_end} should surround the error
|
||||
_("Got an error '{markup_begin}{error}{markup_end}' {time_span_ago}"),
|
||||
fmt::arg("markup_begin", ErrMarkupBegin),
|
||||
fmt::arg("error", Glib::Markup::escape_text(tracker.lastAnnounceResult)),
|
||||
fmt::arg("error", Glib::Markup::escape_text(std::data(tracker.lastAnnounceResult))),
|
||||
fmt::arg("markup_end", ErrMarkupEnd),
|
||||
fmt::arg("time_span_ago", time_span_ago));
|
||||
}
|
||||
|
@ -1859,7 +1862,7 @@ void appendAnnounceInfo(tr_tracker_view const& tracker, time_t const now, Gtk::T
|
|||
|
||||
void appendScrapeInfo(tr_tracker_view const& tracker, time_t const now, Gtk::TextDirection direction, std::ostream& gstr)
|
||||
{
|
||||
auto const dir_mark = text_dir_mark[static_cast<int>(direction)];
|
||||
auto const dir_mark = text_dir_mark.at(static_cast<int>(direction));
|
||||
|
||||
if (tracker.hasScraped)
|
||||
{
|
||||
|
@ -1885,7 +1888,7 @@ void appendScrapeInfo(tr_tracker_view const& tracker, time_t const now, Gtk::Tex
|
|||
gstr << fmt::format(
|
||||
// {markup_begin} and {markup_end} should surround the error text
|
||||
_("Got a scrape error '{markup_begin}{error}{markup_end}' {time_span_ago}"),
|
||||
fmt::arg("error", Glib::Markup::escape_text(tracker.lastScrapeResult)),
|
||||
fmt::arg("error", Glib::Markup::escape_text(std::data(tracker.lastScrapeResult))),
|
||||
fmt::arg("time_span_ago", time_span_ago),
|
||||
fmt::arg("markup_begin", ErrMarkupBegin),
|
||||
fmt::arg("markup_end", ErrMarkupEnd));
|
||||
|
@ -1934,7 +1937,7 @@ void buildTrackerSummary(
|
|||
Gtk::TextDirection direction)
|
||||
{
|
||||
// hostname
|
||||
gstr << text_dir_mark[static_cast<int>(direction)];
|
||||
gstr << text_dir_mark.at(static_cast<int>(direction));
|
||||
gstr << (tracker.isBackup ? "<i>" : "<b>");
|
||||
gstr << Glib::Markup::escape_text(!key.empty() ? fmt::format(FMT_STRING("{:s} - {:s}"), tracker.host, key) : tracker.host);
|
||||
gstr << (tracker.isBackup ? "</i>" : "</b>");
|
||||
|
@ -2167,6 +2170,7 @@ public:
|
|||
DetailsDialog& parent,
|
||||
Glib::RefPtr<Session> const& core,
|
||||
tr_torrent const* torrent);
|
||||
~EditTrackersDialog() override = default;
|
||||
|
||||
TR_DISABLE_COPY_MOVE(EditTrackersDialog)
|
||||
|
||||
|
@ -2285,6 +2289,7 @@ public:
|
|||
DetailsDialog& parent,
|
||||
Glib::RefPtr<Session> const& core,
|
||||
tr_torrent const* torrent);
|
||||
~AddTrackerDialog() override = default;
|
||||
|
||||
TR_DISABLE_COPY_MOVE(AddTrackerDialog)
|
||||
|
||||
|
@ -2344,14 +2349,12 @@ void AddTrackerDialog::on_response(int response)
|
|||
if (tr_urlIsValidTracker(url.c_str()))
|
||||
{
|
||||
tr_variant top;
|
||||
tr_variant* args;
|
||||
tr_variant* trackers;
|
||||
|
||||
tr_variantInitDict(&top, 2);
|
||||
tr_variantDictAddStrView(&top, TR_KEY_method, "torrent-set"sv);
|
||||
args = tr_variantDictAddDict(&top, TR_KEY_arguments, 2);
|
||||
auto* const args = tr_variantDictAddDict(&top, TR_KEY_arguments, 2);
|
||||
tr_variantDictAddInt(args, TR_KEY_id, torrent_id_);
|
||||
trackers = tr_variantDictAddList(args, TR_KEY_trackerAdd, 1);
|
||||
auto* const trackers = tr_variantDictAddList(args, TR_KEY_trackerAdd, 1);
|
||||
tr_variantListAddStr(trackers, url.raw());
|
||||
|
||||
core_->exec(&top);
|
||||
|
@ -2395,14 +2398,12 @@ void DetailsDialog::Impl::on_tracker_list_remove_button_clicked()
|
|||
auto const torrent_id = iter->get_value(tracker_cols.torrent_id);
|
||||
auto const tracker_id = iter->get_value(tracker_cols.tracker_id);
|
||||
tr_variant top;
|
||||
tr_variant* args;
|
||||
tr_variant* trackers;
|
||||
|
||||
tr_variantInitDict(&top, 2);
|
||||
tr_variantDictAddStrView(&top, TR_KEY_method, "torrent-set"sv);
|
||||
args = tr_variantDictAddDict(&top, TR_KEY_arguments, 2);
|
||||
auto* const args = tr_variantDictAddDict(&top, TR_KEY_arguments, 2);
|
||||
tr_variantDictAddInt(args, TR_KEY_id, torrent_id);
|
||||
trackers = tr_variantDictAddList(args, TR_KEY_trackerRemove, 1);
|
||||
auto* const trackers = tr_variantDictAddList(args, TR_KEY_trackerRemove, 1);
|
||||
tr_variantListAddInt(trackers, tracker_id);
|
||||
|
||||
core_->exec(&top);
|
||||
|
|
|
@ -35,7 +35,7 @@ struct favicon_data
|
|||
|
||||
Glib::ustring get_url(std::string const& host, size_t image_type)
|
||||
{
|
||||
return fmt::format("http://{}/favicon.{}", host, image_types[image_type]);
|
||||
return fmt::format("http://{}/favicon.{}", host, image_types.at(image_type));
|
||||
}
|
||||
|
||||
std::string favicon_get_cache_dir()
|
||||
|
|
|
@ -302,8 +302,8 @@ void FileList::Impl::refresh()
|
|||
}
|
||||
else
|
||||
{
|
||||
Gtk::SortType order;
|
||||
int sort_column_id;
|
||||
Gtk::SortType order = TR_GTK_SORT_TYPE(ASCENDING);
|
||||
int sort_column_id = 0;
|
||||
store_->get_sort_column_id(sort_column_id, order);
|
||||
|
||||
RefreshData refresh_data{ sort_column_id, false, tor };
|
||||
|
@ -426,8 +426,8 @@ namespace
|
|||
|
||||
struct build_data
|
||||
{
|
||||
Gtk::Widget* w;
|
||||
tr_torrent* tor;
|
||||
Gtk::Widget* w = nullptr;
|
||||
tr_torrent* tor = nullptr;
|
||||
Gtk::TreeStore::iterator iter;
|
||||
Glib::RefPtr<Gtk::TreeStore> store;
|
||||
};
|
||||
|
@ -575,13 +575,27 @@ namespace
|
|||
|
||||
void renderDownload(Gtk::CellRenderer* renderer, Gtk::TreeModel::const_iterator const& iter)
|
||||
{
|
||||
auto* const toggle_renderer = dynamic_cast<Gtk::CellRendererToggle*>(renderer);
|
||||
g_assert(toggle_renderer != nullptr);
|
||||
if (toggle_renderer == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
auto const enabled = iter->get_value(file_cols.enabled);
|
||||
static_cast<Gtk::CellRendererToggle*>(renderer)->property_inconsistent() = enabled == MIXED;
|
||||
static_cast<Gtk::CellRendererToggle*>(renderer)->property_active() = enabled == static_cast<int>(true);
|
||||
toggle_renderer->property_inconsistent() = enabled == MIXED;
|
||||
toggle_renderer->property_active() = enabled == static_cast<int>(true);
|
||||
}
|
||||
|
||||
void renderPriority(Gtk::CellRenderer* renderer, Gtk::TreeModel::const_iterator const& iter)
|
||||
{
|
||||
auto* const text_renderer = dynamic_cast<Gtk::CellRendererText*>(renderer);
|
||||
g_assert(text_renderer != nullptr);
|
||||
if (text_renderer == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Glib::ustring text;
|
||||
|
||||
switch (auto const priority = iter->get_value(file_cols.priority); priority)
|
||||
|
@ -603,7 +617,7 @@ void renderPriority(Gtk::CellRenderer* renderer, Gtk::TreeModel::const_iterator
|
|||
break;
|
||||
}
|
||||
|
||||
static_cast<Gtk::CellRendererText*>(renderer)->property_text() = text;
|
||||
text_renderer->property_text() = text;
|
||||
}
|
||||
|
||||
/* build a filename from tr_torrentGetCurrentDir() + the model's FC_LABELs */
|
||||
|
@ -710,8 +724,8 @@ bool FileList::Impl::onViewPathToggled(Gtk::TreeViewColumn* col, Gtk::TreeModel:
|
|||
*/
|
||||
bool FileList::Impl::getAndSelectEventPath(double view_x, double view_y, Gtk::TreeViewColumn*& col, Gtk::TreeModel::Path& path)
|
||||
{
|
||||
int cell_x;
|
||||
int cell_y;
|
||||
int cell_x = 0;
|
||||
int cell_y = 0;
|
||||
|
||||
if (view_->get_path_at_pos(view_x, view_y, path, col, cell_x, cell_y))
|
||||
{
|
||||
|
@ -729,7 +743,7 @@ bool FileList::Impl::getAndSelectEventPath(double view_x, double view_y, Gtk::Tr
|
|||
|
||||
bool FileList::Impl::onViewButtonPressed(guint button, TrGdkModifierType state, double view_x, double view_y)
|
||||
{
|
||||
Gtk::TreeViewColumn* col;
|
||||
Gtk::TreeViewColumn* col = nullptr;
|
||||
Gtk::TreeModel::Path path;
|
||||
bool handled = false;
|
||||
|
||||
|
@ -747,7 +761,7 @@ struct rename_data
|
|||
{
|
||||
Glib::ustring newname;
|
||||
Glib::ustring path_string;
|
||||
gpointer impl;
|
||||
gpointer impl = nullptr;
|
||||
};
|
||||
|
||||
bool FileList::Impl::on_rename_done_idle(Glib::ustring const& path_string, Glib::ustring const& newname, int error)
|
||||
|
@ -772,7 +786,7 @@ bool FileList::Impl::on_rename_done_idle(Glib::ustring const& path_string, Glib:
|
|||
else
|
||||
{
|
||||
auto w = std::make_shared<Gtk::MessageDialog>(
|
||||
*static_cast<Gtk::Window*>(TR_GTK_WIDGET_GET_ROOT(widget_)),
|
||||
gtr_widget_get_window(widget_),
|
||||
fmt::format(
|
||||
_("Couldn't rename '{old_path}' as '{path}': {error} ({error_code})"),
|
||||
fmt::arg("old_path", path_string),
|
||||
|
@ -931,8 +945,8 @@ FileList::Impl::Impl(
|
|||
{
|
||||
/* add "progress" column */
|
||||
auto const* title = _("Have");
|
||||
int width;
|
||||
int height;
|
||||
int width = 0;
|
||||
int height = 0;
|
||||
view_->create_pango_layout(title)->get_pixel_size(width, height);
|
||||
width += 30; /* room for the sort indicator */
|
||||
auto* rend = Gtk::make_managed<Gtk::CellRendererProgress>();
|
||||
|
@ -948,8 +962,8 @@ FileList::Impl::Impl(
|
|||
{
|
||||
/* add "enabled" column */
|
||||
auto const* title = _("Download");
|
||||
int width;
|
||||
int height;
|
||||
int width = 0;
|
||||
int height = 0;
|
||||
view_->create_pango_layout(title)->get_pixel_size(width, height);
|
||||
width += 30; /* room for the sort indicator */
|
||||
auto* rend = Gtk::make_managed<Gtk::CellRendererToggle>();
|
||||
|
@ -965,8 +979,8 @@ FileList::Impl::Impl(
|
|||
{
|
||||
/* add priority column */
|
||||
auto const* title = _("Priority");
|
||||
int width;
|
||||
int height;
|
||||
int width = 0;
|
||||
int height = 0;
|
||||
view_->create_pango_layout(title)->get_pixel_size(width, height);
|
||||
width += 30; /* room for the sort indicator */
|
||||
auto* rend = Gtk::make_managed<Gtk::CellRendererText>();
|
||||
|
|
|
@ -185,7 +185,7 @@ bool tracker_filter_model_update(Glib::RefPtr<Gtk::TreeStore> const& tracker_mod
|
|||
for (size_t i = 0, n = tr_torrentTrackerCount(tor); i < n; ++i)
|
||||
{
|
||||
auto const view = tr_torrentTracker(tor, i);
|
||||
torrent_sites_and_hosts.try_emplace(view.sitename, view.host);
|
||||
torrent_sites_and_hosts.try_emplace(std::data(view.sitename), view.host);
|
||||
}
|
||||
|
||||
for (auto const& [sitename, host] : torrent_sites_and_hosts)
|
||||
|
@ -391,7 +391,7 @@ bool test_tracker(tr_torrent const* tor, int active_tracker_type, Glib::ustring
|
|||
|
||||
for (size_t i = 0, n = tr_torrentTrackerCount(tor); i < n; ++i)
|
||||
{
|
||||
if (tr_torrentTracker(tor, i).sitename == host)
|
||||
if (auto const tracker = tr_torrentTracker(tor, i); std::data(tracker.sitename) == host)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
@ -696,26 +696,18 @@ bool FilterBar::Impl::update_count_label()
|
|||
auto const visibleCount = static_cast<int>(filter_model_->children().size());
|
||||
|
||||
/* get the tracker count */
|
||||
int trackerCount;
|
||||
int trackerCount = 0;
|
||||
if (auto const iter = tracker_->get_active(); iter)
|
||||
{
|
||||
trackerCount = iter->get_value(tracker_filter_cols.count);
|
||||
}
|
||||
else
|
||||
{
|
||||
trackerCount = 0;
|
||||
}
|
||||
|
||||
/* get the activity count */
|
||||
int activityCount;
|
||||
int activityCount = 0;
|
||||
if (auto const iter = activity_->get_active(); iter)
|
||||
{
|
||||
activityCount = iter->get_value(activity_filter_cols.count);
|
||||
}
|
||||
else
|
||||
{
|
||||
activityCount = 0;
|
||||
}
|
||||
|
||||
/* set the text */
|
||||
show_lb_->set_markup_with_mnemonic(
|
||||
|
@ -802,7 +794,7 @@ FilterBar::Impl::Impl(FilterBar& widget, tr_session* session, Glib::RefPtr<Gtk::
|
|||
filter_model_row_inserted_tag_ = filter_model_->signal_row_inserted().connect(
|
||||
[this](auto const& /*path*/, auto const& /*iter*/) { update_count_label_idle(); });
|
||||
|
||||
static_cast<Gtk::TreeStore*>(tracker_->get_model().get())->set_data(SESSION_KEY, session);
|
||||
gtr_ptr_dynamic_cast<Gtk::TreeStore>(tracker_->get_model())->set_data(SESSION_KEY, session);
|
||||
|
||||
filter_model_->set_visible_func(sigc::mem_fun(*this, &Impl::is_row_visible));
|
||||
|
||||
|
@ -855,6 +847,8 @@ T* FilterBar::Impl::get_template_child(char const* name) const
|
|||
auto full_type_name = std::string("gtkmm__CustomObject_");
|
||||
Glib::append_canonical_typename(full_type_name, typeid(FilterBar).name());
|
||||
|
||||
return Glib::wrap(reinterpret_cast<typename T::BaseObjectType*>(
|
||||
gtk_widget_get_template_child(GTK_WIDGET(widget_.gobj()), g_type_from_name(full_type_name.c_str()), name)));
|
||||
return Glib::wrap(G_TYPE_CHECK_INSTANCE_CAST(
|
||||
gtk_widget_get_template_child(GTK_WIDGET(widget_.gobj()), g_type_from_name(full_type_name.c_str()), name),
|
||||
T::get_base_type(),
|
||||
typename T::BaseObjectType));
|
||||
}
|
||||
|
|
|
@ -296,7 +296,7 @@ Glib::RefPtr<Gio::MenuModel> MainWindow::Impl::createSpeedMenu(
|
|||
Glib::RefPtr<Gio::SimpleActionGroup> const& actions,
|
||||
tr_direction dir)
|
||||
{
|
||||
auto& info = speed_menu_info_[dir];
|
||||
auto& info = speed_menu_info_.at(dir);
|
||||
|
||||
auto m = Gio::Menu::create();
|
||||
|
||||
|
|
|
@ -83,6 +83,7 @@ class MakeDialog::Impl
|
|||
{
|
||||
public:
|
||||
Impl(MakeDialog& dialog, Glib::RefPtr<Gtk::Builder> const& builder, Glib::RefPtr<Session> const& core);
|
||||
~Impl() = default;
|
||||
|
||||
TR_DISABLE_COPY_MOVE(Impl)
|
||||
|
||||
|
|
|
@ -3,8 +3,7 @@
|
|||
// or any future license endorsed by Mnemosyne LLC.
|
||||
// License text can be found in the licenses/ folder.
|
||||
|
||||
#include <cerrno>
|
||||
#include <cstdio>
|
||||
#include <fstream>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
|
||||
|
@ -12,6 +11,7 @@
|
|||
#include <glibmm/i18n.h>
|
||||
|
||||
#include <fmt/core.h>
|
||||
#include <fmt/ostream.h>
|
||||
|
||||
#include <libtransmission/transmission.h>
|
||||
#include <libtransmission/log.h>
|
||||
|
@ -37,7 +37,7 @@ public:
|
|||
Gtk::TreeModelColumn<unsigned int> sequence;
|
||||
Gtk::TreeModelColumn<Glib::ustring> name;
|
||||
Gtk::TreeModelColumn<Glib::ustring> message;
|
||||
Gtk::TreeModelColumn<tr_log_message*> tr_msg;
|
||||
Gtk::TreeModelColumn<tr_log_message const*> tr_msg;
|
||||
};
|
||||
|
||||
MessageLogColumnsModel const message_log_cols;
|
||||
|
@ -179,27 +179,12 @@ Glib::ustring gtr_asctime(time_t t)
|
|||
|
||||
void MessageLogWindow::Impl::doSave(Gtk::Window& parent, Glib::ustring const& filename)
|
||||
{
|
||||
auto* fp = std::fopen(filename.c_str(), "w+");
|
||||
try
|
||||
{
|
||||
auto stream = std::ofstream();
|
||||
stream.exceptions(std::ios_base::failbit | std::ios_base::badbit);
|
||||
stream.open(Glib::locale_from_utf8(filename), std::ios_base::trunc);
|
||||
|
||||
if (fp == nullptr)
|
||||
{
|
||||
auto const errcode = errno;
|
||||
auto w = std::make_shared<Gtk::MessageDialog>(
|
||||
parent,
|
||||
fmt::format(
|
||||
_("Couldn't save '{path}': {error} ({error_code})"),
|
||||
fmt::arg("path", filename),
|
||||
fmt::arg("error", g_strerror(errcode)),
|
||||
fmt::arg("error_code", errcode)),
|
||||
false,
|
||||
TR_GTK_MESSAGE_TYPE(ERROR),
|
||||
TR_GTK_BUTTONS_TYPE(CLOSE));
|
||||
w->set_secondary_text(Glib::strerror(errno));
|
||||
w->signal_response().connect([w](int /*response*/) mutable { w.reset(); });
|
||||
w->show();
|
||||
}
|
||||
else
|
||||
{
|
||||
for (auto const& row : store_->children())
|
||||
{
|
||||
auto const* const node = row.get_value(message_log_cols.tr_msg);
|
||||
|
@ -208,10 +193,24 @@ void MessageLogWindow::Impl::doSave(Gtk::Window& parent, Glib::ustring const& fi
|
|||
auto const it = level_names_.find(node->level);
|
||||
auto const* const level_str = it != std::end(level_names_) ? it->second : "???";
|
||||
|
||||
fmt::print(fp, "{}\t{}\t{}\t{}\n", date, level_str, node->name, node->message);
|
||||
fmt::print(stream, "{}\t{}\t{}\t{}\n", date, level_str, node->name, node->message);
|
||||
}
|
||||
|
||||
std::fclose(fp);
|
||||
}
|
||||
catch (std::ios_base::failure const& e)
|
||||
{
|
||||
auto w = std::make_shared<Gtk::MessageDialog>(
|
||||
parent,
|
||||
fmt::format(
|
||||
_("Couldn't save '{path}': {error} ({error_code})"),
|
||||
fmt::arg("path", filename),
|
||||
fmt::arg("error", e.code().message()),
|
||||
fmt::arg("error_code", e.code().value())),
|
||||
false,
|
||||
TR_GTK_MESSAGE_TYPE(ERROR),
|
||||
TR_GTK_BUTTONS_TYPE(CLOSE));
|
||||
w->set_secondary_text(e.code().message());
|
||||
w->signal_response().connect([w](int /*response*/) mutable { w.reset(); });
|
||||
w->show();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -296,7 +295,7 @@ void renderTime(Gtk::CellRendererText* renderer, Gtk::TreeModel::const_iterator
|
|||
|
||||
void appendColumn(Gtk::TreeView* view, Gtk::TreeModelColumnBase const& col)
|
||||
{
|
||||
Gtk::TreeViewColumn* c;
|
||||
Gtk::TreeViewColumn* c = nullptr;
|
||||
|
||||
if (col == message_log_cols.name)
|
||||
{
|
||||
|
@ -349,36 +348,38 @@ namespace
|
|||
|
||||
tr_log_message* addMessages(Glib::RefPtr<Gtk::ListStore> const& store, tr_log_message* head)
|
||||
{
|
||||
tr_log_message* i;
|
||||
static unsigned int sequence = 0;
|
||||
auto const default_name = Glib::get_application_name();
|
||||
|
||||
for (i = head; i != nullptr && i->next != nullptr; i = i->next)
|
||||
while (head != nullptr && head->next != nullptr)
|
||||
{
|
||||
char const* name = !std::empty(i->name) ? i->name.c_str() : default_name.c_str();
|
||||
auto const& message = *head;
|
||||
head = head->next;
|
||||
|
||||
char const* name = !std::empty(message.name) ? message.name.c_str() : default_name.c_str();
|
||||
|
||||
auto row_it = store->prepend();
|
||||
auto& row = *row_it;
|
||||
row[message_log_cols.tr_msg] = i;
|
||||
row[message_log_cols.tr_msg] = &message;
|
||||
row[message_log_cols.name] = name;
|
||||
row[message_log_cols.message] = i->message;
|
||||
row[message_log_cols.message] = message.message;
|
||||
row[message_log_cols.sequence] = ++sequence;
|
||||
|
||||
/* if it's an error message, dump it to the terminal too */
|
||||
if (i->level == TR_LOG_ERROR)
|
||||
if (message.level == TR_LOG_ERROR)
|
||||
{
|
||||
auto gstr = fmt::format("{}:{} {}", i->file, i->line, i->message);
|
||||
auto gstr = fmt::format("{}:{} {}", message.file, message.line, message.message);
|
||||
|
||||
if (!std::empty(i->name))
|
||||
if (!std::empty(message.name))
|
||||
{
|
||||
gstr += fmt::format(" ({})", i->name.c_str());
|
||||
gstr += fmt::format(" ({})", message.name.c_str());
|
||||
}
|
||||
|
||||
g_warning("%s", gstr.c_str());
|
||||
gtr_warning(gstr);
|
||||
}
|
||||
}
|
||||
|
||||
return i; /* tail */
|
||||
return head; /* tail */
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
@ -447,6 +448,13 @@ MessageLogWindow::Impl::Impl(
|
|||
: window_(window)
|
||||
, core_(core)
|
||||
, view_(gtr_get_widget<Gtk::TreeView>(builder, "messages_view"))
|
||||
, store_(Gtk::ListStore::create(message_log_cols))
|
||||
, filter_(Gtk::TreeModelFilter::create(store_))
|
||||
, sort_(Gtk::TreeModelSort::create(filter_))
|
||||
, maxLevel_(static_cast<tr_log_level>(gtr_pref_int_get(TR_KEY_message_level)))
|
||||
, refresh_tag_(Glib::signal_timeout().connect_seconds(
|
||||
sigc::mem_fun(*this, &Impl::onRefresh),
|
||||
SECONDARY_WINDOW_REFRESH_INTERVAL_SECONDS))
|
||||
, level_names_{ {
|
||||
{ TR_LOG_CRITICAL, C_("Logging level", "Critical") },
|
||||
{ TR_LOG_ERROR, C_("Logging level", "Error") },
|
||||
|
@ -485,15 +493,10 @@ MessageLogWindow::Impl::Impl(
|
|||
*** messages
|
||||
**/
|
||||
|
||||
store_ = Gtk::ListStore::create(message_log_cols);
|
||||
|
||||
addMessages(store_, myHead);
|
||||
onRefresh(); /* much faster to populate *before* it has listeners */
|
||||
|
||||
filter_ = Gtk::TreeModelFilter::create(store_);
|
||||
sort_ = Gtk::TreeModelSort::create(filter_);
|
||||
sort_->set_sort_column(message_log_cols.sequence, TR_GTK_SORT_TYPE(ASCENDING));
|
||||
maxLevel_ = static_cast<tr_log_level>(gtr_pref_int_get(TR_KEY_message_level));
|
||||
filter_->set_visible_func(sigc::mem_fun(*this, &Impl::isRowVisible));
|
||||
|
||||
view_->set_model(sort_);
|
||||
|
@ -505,9 +508,5 @@ MessageLogWindow::Impl::Impl(
|
|||
appendColumn(view_, message_log_cols.name);
|
||||
appendColumn(view_, message_log_cols.message);
|
||||
|
||||
refresh_tag_ = Glib::signal_timeout().connect_seconds(
|
||||
sigc::mem_fun(*this, &Impl::onRefresh),
|
||||
SECONDARY_WINDOW_REFRESH_INTERVAL_SECONDS);
|
||||
|
||||
scroll_to_bottom();
|
||||
}
|
||||
|
|
|
@ -136,14 +136,11 @@ void dbus_proxy_ready_callback(Glib::RefPtr<Gio::AsyncResult>& res)
|
|||
}
|
||||
catch (Glib::Error const& e)
|
||||
{
|
||||
g_warning(
|
||||
"%s",
|
||||
fmt::format(
|
||||
_("Couldn't create proxy for '{bus}': {error} ({error_code})"),
|
||||
fmt::arg("bus", NotificationsDbusName),
|
||||
fmt::arg("error", TR_GLIB_EXCEPTION_WHAT(e)),
|
||||
fmt::arg("error_code", e.code()))
|
||||
.c_str());
|
||||
gtr_warning(fmt::format(
|
||||
_("Couldn't create proxy for '{bus}': {error} ({error_code})"),
|
||||
fmt::arg("bus", NotificationsDbusName),
|
||||
fmt::arg("error", TR_GLIB_EXCEPTION_WHAT(e)),
|
||||
fmt::arg("error_code", e.code())));
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -66,6 +66,7 @@ public:
|
|||
Glib::RefPtr<Gtk::Builder> const& builder,
|
||||
Glib::RefPtr<Session> const& core,
|
||||
std::unique_ptr<tr_ctor, void (*)(tr_ctor*)> ctor);
|
||||
~Impl() = default;
|
||||
|
||||
TR_DISABLE_COPY_MOVE(Impl)
|
||||
|
||||
|
@ -289,7 +290,7 @@ OptionsDialog::Impl::Impl(
|
|||
destination_chooser->signal_selection_changed().connect([this, destination_chooser]()
|
||||
{ downloadDirChanged(destination_chooser); });
|
||||
|
||||
bool flag;
|
||||
bool flag = false;
|
||||
if (!tr_ctorGetPaused(ctor_.get(), TR_FORCE, &flag))
|
||||
{
|
||||
g_assert_not_reached();
|
||||
|
|
|
@ -14,6 +14,7 @@ class PathButton::Impl
|
|||
{
|
||||
public:
|
||||
explicit Impl(PathButton& widget);
|
||||
~Impl() = default;
|
||||
|
||||
TR_DISABLE_COPY_MOVE(Impl)
|
||||
|
||||
|
@ -133,7 +134,7 @@ void PathButton::Impl::show_dialog()
|
|||
auto const title = title_.get_value();
|
||||
|
||||
auto dialog = std::make_shared<Gtk::FileChooserDialog>(!title.empty() ? title : _("Select a File"), action_.get_value());
|
||||
dialog->set_transient_for(*static_cast<Gtk::Window*>(widget_.get_root()));
|
||||
dialog->set_transient_for(gtr_widget_get_window(widget_));
|
||||
dialog->add_button(_("_Cancel"), Gtk::ResponseType::CANCEL);
|
||||
dialog->add_button(_("_Open"), Gtk::ResponseType::ACCEPT);
|
||||
dialog->set_modal(true);
|
||||
|
|
|
@ -129,7 +129,7 @@ tr_variant* gtr_pref_get_all()
|
|||
|
||||
int64_t gtr_pref_int_get(tr_quark const key)
|
||||
{
|
||||
int64_t i;
|
||||
int64_t i = 0;
|
||||
|
||||
return tr_variantDictFindInt(getPrefs(), key, &i) ? i : 0;
|
||||
}
|
||||
|
@ -141,7 +141,7 @@ void gtr_pref_int_set(tr_quark const key, int64_t value)
|
|||
|
||||
double gtr_pref_double_get(tr_quark const key)
|
||||
{
|
||||
double d;
|
||||
double d = 0;
|
||||
|
||||
return tr_variantDictFindReal(getPrefs(), key, &d) ? d : 0.0;
|
||||
}
|
||||
|
@ -157,7 +157,7 @@ void gtr_pref_double_set(tr_quark const key, double value)
|
|||
|
||||
bool gtr_pref_flag_get(tr_quark const key)
|
||||
{
|
||||
bool boolVal;
|
||||
bool boolVal = false;
|
||||
|
||||
return tr_variantDictFindBool(getPrefs(), key, &boolVal) ? boolVal : false;
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
205
gtk/Session.cc
205
gtk/Session.cc
|
@ -51,7 +51,7 @@ TrVariantPtr create_variant(tr_variant&& other)
|
|||
[](tr_variant* ptr)
|
||||
{
|
||||
tr_variantClear(ptr);
|
||||
delete ptr;
|
||||
std::default_delete<tr_variant>()(ptr);
|
||||
});
|
||||
*result = std::move(other);
|
||||
tr_variantInitBool(&other, false);
|
||||
|
@ -109,13 +109,35 @@ public:
|
|||
|
||||
void commit_prefs_change(tr_quark key);
|
||||
|
||||
public:
|
||||
sigc::signal<void(ErrorCode, Glib::ustring const&)> signal_add_error;
|
||||
sigc::signal<void(tr_ctor*)> signal_add_prompt;
|
||||
sigc::signal<void(int)> signal_blocklist_updated;
|
||||
sigc::signal<void(bool)> signal_busy;
|
||||
sigc::signal<void(tr_quark)> signal_prefs_changed;
|
||||
sigc::signal<void(bool)> signal_port_tested;
|
||||
auto& signal_add_error()
|
||||
{
|
||||
return signal_add_error_;
|
||||
}
|
||||
|
||||
auto& signal_add_prompt()
|
||||
{
|
||||
return signal_add_prompt_;
|
||||
}
|
||||
|
||||
auto& signal_blocklist_updated()
|
||||
{
|
||||
return signal_blocklist_updated_;
|
||||
}
|
||||
|
||||
auto& signal_busy()
|
||||
{
|
||||
return signal_busy_;
|
||||
}
|
||||
|
||||
auto& signal_prefs_changed()
|
||||
{
|
||||
return signal_prefs_changed_;
|
||||
}
|
||||
|
||||
auto& signal_port_tested()
|
||||
{
|
||||
return signal_port_tested_;
|
||||
}
|
||||
|
||||
private:
|
||||
Glib::RefPtr<Session> get_core_ptr() const;
|
||||
|
@ -157,6 +179,13 @@ private:
|
|||
private:
|
||||
Session& core_;
|
||||
|
||||
sigc::signal<void(ErrorCode, Glib::ustring const&)> signal_add_error_;
|
||||
sigc::signal<void(tr_ctor*)> signal_add_prompt_;
|
||||
sigc::signal<void(int)> signal_blocklist_updated_;
|
||||
sigc::signal<void(bool)> signal_busy_;
|
||||
sigc::signal<void(tr_quark)> signal_prefs_changed_;
|
||||
sigc::signal<void(bool)> signal_port_tested_;
|
||||
|
||||
Glib::RefPtr<Gio::FileMonitor> monitor_;
|
||||
sigc::connection monitor_tag_;
|
||||
Glib::RefPtr<Gio::File> monitor_dir_;
|
||||
|
@ -253,7 +282,7 @@ void Session::Impl::add_to_busy(int addMe)
|
|||
|
||||
if (wasBusy != is_busy())
|
||||
{
|
||||
signal_busy.emit(is_busy());
|
||||
signal_busy_.emit(is_busy());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -304,69 +333,15 @@ int compare_eta(int a, int b)
|
|||
return a < b ? 1 : -1;
|
||||
}
|
||||
|
||||
int compare_double(double a, double b)
|
||||
template<typename T>
|
||||
int compare_generic(T&& a, T&& b)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (a < b)
|
||||
{
|
||||
ret = -1;
|
||||
}
|
||||
else if (a > b)
|
||||
{
|
||||
ret = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int compare_uint64(uint64_t a, uint64_t b)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (a < b)
|
||||
{
|
||||
ret = -1;
|
||||
}
|
||||
else if (a > b)
|
||||
{
|
||||
ret = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int compare_int(int a, int b)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (a < b)
|
||||
{
|
||||
ret = -1;
|
||||
}
|
||||
else if (a > b)
|
||||
{
|
||||
ret = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
return ret;
|
||||
return a < b ? -1 : (a > b ? 1 : 0);
|
||||
}
|
||||
|
||||
int compare_ratio(double a, double b)
|
||||
{
|
||||
int ret;
|
||||
int ret = 0;
|
||||
|
||||
if ((int)a == TR_RATIO_INF && (int)b == TR_RATIO_INF)
|
||||
{
|
||||
|
@ -382,27 +357,7 @@ int compare_ratio(double a, double b)
|
|||
}
|
||||
else
|
||||
{
|
||||
ret = compare_double(a, b);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int compare_time(time_t a, time_t b)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (a < b)
|
||||
{
|
||||
ret = -1;
|
||||
}
|
||||
else if (a > b)
|
||||
{
|
||||
ret = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = 0;
|
||||
ret = compare_generic(a, b);
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
@ -452,13 +407,13 @@ int compare_by_activity(Gtk::TreeModel::const_iterator const& a, Gtk::TreeModel:
|
|||
auto const bUp = b->get_value(torrent_cols.speed_up);
|
||||
auto const bDown = b->get_value(torrent_cols.speed_down);
|
||||
|
||||
ret = compare_double(aUp + aDown, bUp + bDown);
|
||||
ret = compare_generic(aUp + aDown, bUp + bDown);
|
||||
|
||||
if (ret == 0)
|
||||
{
|
||||
auto const* const sa = tr_torrentStatCached(ta);
|
||||
auto const* const sb = tr_torrentStatCached(tb);
|
||||
ret = compare_uint64(sa->peersSendingToUs + sa->peersGettingFromUs, sb->peersSendingToUs + sb->peersGettingFromUs);
|
||||
ret = compare_generic(sa->peersSendingToUs + sa->peersGettingFromUs, sb->peersSendingToUs + sb->peersGettingFromUs);
|
||||
}
|
||||
|
||||
if (ret == 0)
|
||||
|
@ -473,7 +428,7 @@ int compare_by_age(Gtk::TreeModel::const_iterator const& a, Gtk::TreeModel::cons
|
|||
{
|
||||
auto* const ta = static_cast<tr_torrent*>(a->get_value(torrent_cols.torrent));
|
||||
auto* const tb = static_cast<tr_torrent*>(b->get_value(torrent_cols.torrent));
|
||||
int ret = compare_time(tr_torrentStatCached(ta)->addedDate, tr_torrentStatCached(tb)->addedDate);
|
||||
int ret = compare_generic(tr_torrentStatCached(ta)->addedDate, tr_torrentStatCached(tb)->addedDate);
|
||||
|
||||
if (ret == 0)
|
||||
{
|
||||
|
@ -487,7 +442,7 @@ int compare_by_size(Gtk::TreeModel::const_iterator const& a, Gtk::TreeModel::con
|
|||
{
|
||||
auto const size_a = tr_torrentTotalSize(static_cast<tr_torrent*>(a->get_value(torrent_cols.torrent)));
|
||||
auto const size_b = tr_torrentTotalSize(static_cast<tr_torrent*>(b->get_value(torrent_cols.torrent)));
|
||||
int ret = compare_uint64(size_a, size_b);
|
||||
int ret = compare_generic(size_a, size_b);
|
||||
|
||||
if (ret == 0)
|
||||
{
|
||||
|
@ -501,11 +456,11 @@ int compare_by_progress(Gtk::TreeModel::const_iterator const& a, Gtk::TreeModel:
|
|||
{
|
||||
auto const* const sa = tr_torrentStatCached(static_cast<tr_torrent*>(a->get_value(torrent_cols.torrent)));
|
||||
auto const* const sb = tr_torrentStatCached(static_cast<tr_torrent*>(b->get_value(torrent_cols.torrent)));
|
||||
int ret = compare_double(sa->percentComplete, sb->percentComplete);
|
||||
int ret = compare_generic(sa->percentComplete, sb->percentComplete);
|
||||
|
||||
if (ret == 0)
|
||||
{
|
||||
ret = compare_double(sa->seedRatioPercentDone, sb->seedRatioPercentDone);
|
||||
ret = compare_generic(sa->seedRatioPercentDone, sb->seedRatioPercentDone);
|
||||
}
|
||||
|
||||
if (ret == 0)
|
||||
|
@ -534,7 +489,7 @@ int compare_by_state(Gtk::TreeModel::const_iterator const& a, Gtk::TreeModel::co
|
|||
{
|
||||
auto const sa = a->get_value(torrent_cols.activity);
|
||||
auto const sb = b->get_value(torrent_cols.activity);
|
||||
int ret = compare_int(sa, sb);
|
||||
int ret = compare_generic(sa, sb);
|
||||
|
||||
if (ret == 0)
|
||||
{
|
||||
|
@ -638,13 +593,12 @@ void rename_torrent(Glib::RefPtr<Gio::File> const& file)
|
|||
}
|
||||
catch (Glib::Error const& e)
|
||||
{
|
||||
auto const errmsg = fmt::format(
|
||||
gtr_message(fmt::format(
|
||||
_("Couldn't rename '{old_path}' as '{path}': {error} ({error_code})"),
|
||||
fmt::arg("old_path", old_name),
|
||||
fmt::arg("path", new_name),
|
||||
fmt::arg("error", e.what()),
|
||||
fmt::arg("error_code", e.code()));
|
||||
g_message("%s", errmsg.c_str());
|
||||
fmt::arg("error_code", e.code())));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -821,6 +775,7 @@ void Session::Impl::on_pref_changed(tr_quark const key)
|
|||
|
||||
Glib::RefPtr<Session> Session::create(tr_session* session)
|
||||
{
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-owning-memory)
|
||||
return Glib::make_refptr_for_instance(new Session(session));
|
||||
}
|
||||
|
||||
|
@ -847,7 +802,7 @@ Session::Impl::Impl(Session& core, tr_session* session)
|
|||
on_pref_changed(TR_KEY_watch_dir_enabled);
|
||||
on_pref_changed(TR_KEY_peer_limit_global);
|
||||
on_pref_changed(TR_KEY_inhibit_desktop_hibernation);
|
||||
signal_prefs_changed.connect([this](auto key) { on_pref_changed(key); });
|
||||
signal_prefs_changed_.connect([this](auto key) { on_pref_changed(key); });
|
||||
|
||||
tr_sessionSetMetadataCallback(
|
||||
session,
|
||||
|
@ -1065,7 +1020,7 @@ int Session::Impl::add_ctor(tr_ctor* ctor, bool do_prompt, bool do_notify)
|
|||
* don't want to be nagging users to clean up their watch dirs */
|
||||
if (tr_ctorGetSourceFile(ctor) == nullptr || !adding_from_watch_dir_)
|
||||
{
|
||||
signal_add_error.emit(ERR_ADD_TORRENT_DUP, metainfo->name().c_str());
|
||||
signal_add_error_.emit(ERR_ADD_TORRENT_DUP, metainfo->name().c_str());
|
||||
}
|
||||
|
||||
tr_ctorFree(ctor);
|
||||
|
@ -1080,7 +1035,7 @@ int Session::Impl::add_ctor(tr_ctor* ctor, bool do_prompt, bool do_notify)
|
|||
return 0;
|
||||
}
|
||||
|
||||
signal_add_prompt.emit(ctor);
|
||||
signal_add_prompt_.emit(ctor);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1131,15 +1086,14 @@ void Session::Impl::add_file_async_callback(
|
|||
bool do_prompt,
|
||||
bool do_notify)
|
||||
{
|
||||
gsize length;
|
||||
char* contents;
|
||||
|
||||
try
|
||||
{
|
||||
gsize length = 0;
|
||||
char* contents = nullptr;
|
||||
|
||||
if (!file->load_contents_finish(result, contents, length))
|
||||
{
|
||||
auto const errmsg = fmt::format(_("Couldn't read '{path}'"), fmt::arg("path", file->get_parse_name()));
|
||||
g_message("%s", errmsg.c_str());
|
||||
gtr_message(fmt::format(_("Couldn't read '{path}'"), fmt::arg("path", file->get_parse_name())));
|
||||
}
|
||||
else if (tr_ctorSetMetainfo(ctor, contents, length, nullptr))
|
||||
{
|
||||
|
@ -1152,12 +1106,11 @@ void Session::Impl::add_file_async_callback(
|
|||
}
|
||||
catch (Glib::Error const& e)
|
||||
{
|
||||
auto const errmsg = fmt::format(
|
||||
gtr_message(fmt::format(
|
||||
_("Couldn't read '{path}': {error} ({error_code})"),
|
||||
fmt::arg("path", file->get_parse_name()),
|
||||
fmt::arg("error", e.what()),
|
||||
fmt::arg("error_code", e.code()));
|
||||
g_message("%s", errmsg.c_str());
|
||||
fmt::arg("error_code", e.code())));
|
||||
}
|
||||
|
||||
dec_busy();
|
||||
|
@ -1252,7 +1205,7 @@ void Session::torrents_added()
|
|||
void Session::Impl::torrents_added()
|
||||
{
|
||||
update();
|
||||
signal_add_error.emit(ERR_NO_MORE_TORRENTS, {});
|
||||
signal_add_error_.emit(ERR_NO_MORE_TORRENTS, {});
|
||||
}
|
||||
|
||||
void Session::torrent_changed(tr_torrent_id_t id)
|
||||
|
@ -1550,7 +1503,7 @@ void Session::Impl::maybe_inhibit_hibernation()
|
|||
|
||||
void Session::Impl::commit_prefs_change(tr_quark const key)
|
||||
{
|
||||
signal_prefs_changed.emit(key);
|
||||
signal_prefs_changed_.emit(key);
|
||||
gtr_pref_save(session_);
|
||||
}
|
||||
|
||||
|
@ -1620,7 +1573,7 @@ bool core_read_rpc_response_idle(TrVariantPtr const& response)
|
|||
}
|
||||
else
|
||||
{
|
||||
g_warning("%s", fmt::format(_("Couldn't find pending RPC request for tag {tag}"), fmt::arg("tag", tag)).c_str());
|
||||
gtr_warning(fmt::format(_("Couldn't find pending RPC request for tag {tag}"), fmt::arg("tag", tag)));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1642,7 +1595,7 @@ void Session::Impl::send_rpc_request(
|
|||
{
|
||||
if (session_ == nullptr)
|
||||
{
|
||||
g_error("GTK+ client doesn't support connections to remote servers yet.");
|
||||
gtr_error("GTK+ client doesn't support connections to remote servers yet.");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1651,7 +1604,7 @@ void Session::Impl::send_rpc_request(
|
|||
|
||||
/* make the request */
|
||||
#ifdef DEBUG_RPC
|
||||
g_message("%s", fmt::format("request: [{}]", tr_variantToStr(request, TR_VARIANT_FMT_JSON_LEAN)).c_str());
|
||||
gtr_message(fmt::format("request: [{}]", tr_variantToStr(request, TR_VARIANT_FMT_JSON_LEAN)));
|
||||
#endif
|
||||
|
||||
tr_rpc_request_exec_json(session_, request, core_read_rpc_response, nullptr);
|
||||
|
@ -1676,8 +1629,8 @@ void Session::port_test()
|
|||
tag,
|
||||
[this](auto* response)
|
||||
{
|
||||
tr_variant* args;
|
||||
bool is_open;
|
||||
tr_variant* args = nullptr;
|
||||
bool is_open = false;
|
||||
|
||||
if (!tr_variantDictFindDict(response, TR_KEY_arguments, &args) ||
|
||||
!tr_variantDictFindBool(args, TR_KEY_port_is_open, &is_open))
|
||||
|
@ -1685,7 +1638,7 @@ void Session::port_test()
|
|||
is_open = false;
|
||||
}
|
||||
|
||||
impl_->signal_port_tested.emit(is_open);
|
||||
impl_->signal_port_tested().emit(is_open);
|
||||
});
|
||||
tr_variantClear(&request);
|
||||
}
|
||||
|
@ -1708,8 +1661,8 @@ void Session::blocklist_update()
|
|||
tag,
|
||||
[this](auto* response)
|
||||
{
|
||||
tr_variant* args;
|
||||
int64_t ruleCount;
|
||||
tr_variant* args = nullptr;
|
||||
int64_t ruleCount = 0;
|
||||
|
||||
if (!tr_variantDictFindDict(response, TR_KEY_arguments, &args) ||
|
||||
!tr_variantDictFindInt(args, TR_KEY_blocklist_size, &ruleCount))
|
||||
|
@ -1722,7 +1675,7 @@ void Session::blocklist_update()
|
|||
gtr_pref_int_set(TR_KEY_blocklist_date, tr_time());
|
||||
}
|
||||
|
||||
impl_->signal_blocklist_updated.emit(ruleCount);
|
||||
impl_->signal_blocklist_updated().emit(ruleCount);
|
||||
});
|
||||
tr_variantClear(&request);
|
||||
}
|
||||
|
@ -1802,30 +1755,30 @@ void Session::open_folder(tr_torrent_id_t torrent_id) const
|
|||
|
||||
sigc::signal<void(Session::ErrorCode, Glib::ustring const&)>& Session::signal_add_error()
|
||||
{
|
||||
return impl_->signal_add_error;
|
||||
return impl_->signal_add_error();
|
||||
}
|
||||
|
||||
sigc::signal<void(tr_ctor*)>& Session::signal_add_prompt()
|
||||
{
|
||||
return impl_->signal_add_prompt;
|
||||
return impl_->signal_add_prompt();
|
||||
}
|
||||
|
||||
sigc::signal<void(int)>& Session::signal_blocklist_updated()
|
||||
{
|
||||
return impl_->signal_blocklist_updated;
|
||||
return impl_->signal_blocklist_updated();
|
||||
}
|
||||
|
||||
sigc::signal<void(bool)>& Session::signal_busy()
|
||||
{
|
||||
return impl_->signal_busy;
|
||||
return impl_->signal_busy();
|
||||
}
|
||||
|
||||
sigc::signal<void(tr_quark)>& Session::signal_prefs_changed()
|
||||
{
|
||||
return impl_->signal_prefs_changed;
|
||||
return impl_->signal_prefs_changed();
|
||||
}
|
||||
|
||||
sigc::signal<void(bool)>& Session::signal_port_tested()
|
||||
{
|
||||
return impl_->signal_port_tested;
|
||||
return impl_->signal_port_tested();
|
||||
}
|
||||
|
|
|
@ -29,16 +29,12 @@
|
|||
#include "SystemTrayIcon.h"
|
||||
#include "Utils.h"
|
||||
|
||||
#define TR_SYS_TRAY_IMPL_NONE 0
|
||||
#define TR_SYS_TRAY_IMPL_APPINDICATOR 1
|
||||
#define TR_SYS_TRAY_IMPL_STATUS_ICON 2
|
||||
|
||||
#ifdef HAVE_APPINDICATOR
|
||||
#define TR_SYS_TRAY_IMPL TR_SYS_TRAY_IMPL_APPINDICATOR
|
||||
#define TR_SYS_TRAY_IMPL_APPINDICATOR
|
||||
#elif !GTKMM_CHECK_VERSION(4, 0, 0)
|
||||
#define TR_SYS_TRAY_IMPL TR_SYS_TRAY_IMPL_STATUS_ICON
|
||||
#define TR_SYS_TRAY_IMPL_STATUS_ICON
|
||||
#else
|
||||
#define TR_SYS_TRAY_IMPL TR_SYS_TRAY_IMPL_NONE
|
||||
#define TR_SYS_TRAY_IMPL_NONE
|
||||
#endif
|
||||
|
||||
using namespace std::literals;
|
||||
|
@ -46,12 +42,12 @@ using namespace std::literals;
|
|||
namespace
|
||||
{
|
||||
|
||||
#if TR_SYS_TRAY_IMPL != TR_SYS_TRAY_IMPL_NONE
|
||||
#if !defined(TR_SYS_TRAY_IMPL_NONE)
|
||||
auto const TrayIconName = Glib::ustring("transmission-tray-icon"s);
|
||||
auto const AppIconName = Glib::ustring("transmission"s);
|
||||
#endif
|
||||
|
||||
#if TR_SYS_TRAY_IMPL == TR_SYS_TRAY_IMPL_APPINDICATOR
|
||||
#if defined(TR_SYS_TRAY_IMPL_APPINDICATOR)
|
||||
auto const AppName = Glib::ustring("transmission-gtk"s);
|
||||
#endif
|
||||
|
||||
|
@ -76,18 +72,18 @@ private:
|
|||
private:
|
||||
Glib::RefPtr<Session> const core_;
|
||||
|
||||
#if TR_SYS_TRAY_IMPL != TR_SYS_TRAY_IMPL_NONE
|
||||
#if !defined(TR_SYS_TRAY_IMPL_NONE)
|
||||
Gtk::Menu* menu_;
|
||||
#endif
|
||||
|
||||
#if TR_SYS_TRAY_IMPL == TR_SYS_TRAY_IMPL_APPINDICATOR
|
||||
#if defined(TR_SYS_TRAY_IMPL_APPINDICATOR)
|
||||
AppIndicator* indicator_;
|
||||
#elif TR_SYS_TRAY_IMPL == TR_SYS_TRAY_IMPL_STATUS_ICON
|
||||
#elif defined(TR_SYS_TRAY_IMPL_STATUS_ICON)
|
||||
Glib::RefPtr<Gtk::StatusIcon> icon_;
|
||||
#endif
|
||||
};
|
||||
|
||||
#if TR_SYS_TRAY_IMPL == TR_SYS_TRAY_IMPL_APPINDICATOR
|
||||
#if defined(TR_SYS_TRAY_IMPL_APPINDICATOR)
|
||||
|
||||
SystemTrayIcon::Impl::~Impl()
|
||||
{
|
||||
|
@ -98,7 +94,7 @@ void SystemTrayIcon::Impl::refresh()
|
|||
{
|
||||
}
|
||||
|
||||
#elif TR_SYS_TRAY_IMPL == TR_SYS_TRAY_IMPL_STATUS_ICON
|
||||
#elif defined(TR_SYS_TRAY_IMPL_STATUS_ICON)
|
||||
|
||||
SystemTrayIcon::Impl::~Impl() = default;
|
||||
|
||||
|
@ -126,7 +122,7 @@ SystemTrayIcon::Impl::~Impl() = default;
|
|||
namespace
|
||||
{
|
||||
|
||||
#if TR_SYS_TRAY_IMPL != TR_SYS_TRAY_IMPL_NONE
|
||||
#if !defined(TR_SYS_TRAY_IMPL_NONE)
|
||||
|
||||
Glib::ustring getIconName()
|
||||
{
|
||||
|
@ -162,14 +158,14 @@ SystemTrayIcon::~SystemTrayIcon() = default;
|
|||
|
||||
void SystemTrayIcon::refresh()
|
||||
{
|
||||
#if TR_SYS_TRAY_IMPL != TR_SYS_TRAY_IMPL_NONE
|
||||
#if !defined(TR_SYS_TRAY_IMPL_NONE)
|
||||
impl_->refresh();
|
||||
#endif
|
||||
}
|
||||
|
||||
bool SystemTrayIcon::is_available()
|
||||
{
|
||||
#if TR_SYS_TRAY_IMPL != TR_SYS_TRAY_IMPL_NONE
|
||||
#if !defined(TR_SYS_TRAY_IMPL_NONE)
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
|
@ -184,18 +180,18 @@ std::unique_ptr<SystemTrayIcon> SystemTrayIcon::create(Gtk::Window& main_window,
|
|||
SystemTrayIcon::Impl::Impl([[maybe_unused]] Gtk::Window& main_window, Glib::RefPtr<Session> const& core)
|
||||
: core_(core)
|
||||
{
|
||||
#if TR_SYS_TRAY_IMPL != TR_SYS_TRAY_IMPL_NONE
|
||||
#if !defined(TR_SYS_TRAY_IMPL_NONE)
|
||||
auto const icon_name = getIconName();
|
||||
menu_ = Gtk::make_managed<Gtk::Menu>(gtr_action_get_object<Gio::Menu>("icon-popup"));
|
||||
menu_->attach_to_widget(main_window);
|
||||
#endif
|
||||
|
||||
#if TR_SYS_TRAY_IMPL == TR_SYS_TRAY_IMPL_APPINDICATOR
|
||||
#if defined(TR_SYS_TRAY_IMPL_APPINDICATOR)
|
||||
indicator_ = app_indicator_new(AppName.c_str(), icon_name.c_str(), APP_INDICATOR_CATEGORY_SYSTEM_SERVICES);
|
||||
app_indicator_set_status(indicator_, APP_INDICATOR_STATUS_ACTIVE);
|
||||
app_indicator_set_menu(indicator_, Glib::unwrap(menu_));
|
||||
app_indicator_set_title(indicator_, Glib::get_application_name().c_str());
|
||||
#elif TR_SYS_TRAY_IMPL == TR_SYS_TRAY_IMPL_STATUS_ICON
|
||||
#elif defined(TR_SYS_TRAY_IMPL_STATUS_ICON)
|
||||
icon_ = Gtk::StatusIcon::create(icon_name);
|
||||
icon_->signal_activate().connect(sigc::mem_fun(*this, &Impl::activated));
|
||||
icon_->signal_popup_menu().connect(sigc::mem_fun(*this, &Impl::popup));
|
||||
|
|
|
@ -29,9 +29,6 @@
|
|||
****
|
||||
***/
|
||||
|
||||
#define REQ_HEIGHT(Obj) IF_GTKMM4((Obj).get_height(), (Obj).height)
|
||||
#define REQ_WIDTH(Obj) IF_GTKMM4((Obj).get_width(), (Obj).width)
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
|
@ -41,6 +38,16 @@ auto const SmallScale = 0.9;
|
|||
auto const CompactIconSize = IF_GTKMM4(Gtk::IconSize::NORMAL, Gtk::ICON_SIZE_MENU);
|
||||
auto const FullIconSize = IF_GTKMM4(Gtk::IconSize::LARGE, Gtk::ICON_SIZE_DND);
|
||||
|
||||
auto get_height(Gtk::Requisition const& req)
|
||||
{
|
||||
return req.IF_GTKMM4(get_height(), height);
|
||||
}
|
||||
|
||||
auto get_width(Gtk::Requisition const& req)
|
||||
{
|
||||
return req.IF_GTKMM4(get_width(), width);
|
||||
}
|
||||
|
||||
auto getProgressString(tr_torrent const* tor, uint64_t total_size, tr_stat const* st)
|
||||
{
|
||||
Glib::ustring gstr;
|
||||
|
@ -48,7 +55,7 @@ auto getProgressString(tr_torrent const* tor, uint64_t total_size, tr_stat const
|
|||
bool const isDone = st->leftUntilDone == 0;
|
||||
uint64_t const haveTotal = st->haveUnchecked + st->haveValid;
|
||||
bool const isSeed = st->haveValid >= total_size;
|
||||
double seedRatio;
|
||||
double seedRatio = 0;
|
||||
bool const hasSeedRatio = tr_torrentGetSeedRatio(tor, &seedRatio);
|
||||
|
||||
if (!isDone) // downloading
|
||||
|
@ -331,20 +338,30 @@ public:
|
|||
Gdk::Rectangle const& background_area,
|
||||
Gtk::CellRendererState flags);
|
||||
|
||||
public:
|
||||
Glib::Property<gpointer> torrent;
|
||||
Glib::Property<int> bar_height;
|
||||
auto& property_torrent()
|
||||
{
|
||||
return property_torrent_;
|
||||
}
|
||||
|
||||
/* Use this instead of tr_stat.pieceUploadSpeed so that the model can
|
||||
control when the speed displays get updated. This is done to keep
|
||||
the individual torrents' speeds and the status bar's overall speed
|
||||
in sync even if they refresh at slightly different times */
|
||||
Glib::Property<double> upload_speed_KBps;
|
||||
auto& property_bar_height()
|
||||
{
|
||||
return property_bar_height_;
|
||||
}
|
||||
|
||||
/* @see upload_speed_Bps */
|
||||
Glib::Property<double> download_speed_KBps;
|
||||
auto& property_upload_speed_KBps()
|
||||
{
|
||||
return property_upload_speed_KBps_;
|
||||
}
|
||||
|
||||
Glib::Property<bool> compact;
|
||||
auto& property_download_speed_KBps()
|
||||
{
|
||||
return property_download_speed_KBps_;
|
||||
}
|
||||
|
||||
auto& property_compact()
|
||||
{
|
||||
return property_compact_;
|
||||
}
|
||||
|
||||
private:
|
||||
void render_progress_bar(
|
||||
|
@ -366,6 +383,12 @@ private:
|
|||
private:
|
||||
TorrentCellRenderer& renderer_;
|
||||
|
||||
Glib::Property<gpointer> property_torrent_;
|
||||
Glib::Property<int> property_bar_height_;
|
||||
Glib::Property<double> property_upload_speed_KBps_;
|
||||
Glib::Property<double> property_download_speed_KBps_;
|
||||
Glib::Property<bool> property_compact_;
|
||||
|
||||
Gtk::CellRendererText* text_renderer_ = nullptr;
|
||||
Gtk::CellRendererProgress* progress_renderer_ = nullptr;
|
||||
Gtk::CellRendererPixbuf* icon_renderer_ = nullptr;
|
||||
|
@ -421,19 +444,23 @@ void TorrentCellRenderer::Impl::set_icon(
|
|||
|
||||
void TorrentCellRenderer::Impl::get_size_compact(Gtk::Widget& widget, int& width, int& height) const
|
||||
{
|
||||
int xpad;
|
||||
int ypad;
|
||||
int xpad = 0;
|
||||
int ypad = 0;
|
||||
Gtk::Requisition min_size;
|
||||
Gtk::Requisition icon_size;
|
||||
Gtk::Requisition name_size;
|
||||
Gtk::Requisition stat_size;
|
||||
|
||||
auto* const tor = static_cast<tr_torrent*>(torrent.get_value());
|
||||
auto* const tor = static_cast<tr_torrent*>(property_torrent_.get_value());
|
||||
auto const* const st = tr_torrentStatCached(tor);
|
||||
|
||||
auto const icon = get_icon(tor);
|
||||
auto const name = Glib::ustring(tr_torrentName(tor));
|
||||
auto const gstr_stat = getShortStatusString(tor, st, upload_speed_KBps.get_value(), download_speed_KBps.get_value());
|
||||
auto const gstr_stat = getShortStatusString(
|
||||
tor,
|
||||
st,
|
||||
property_upload_speed_KBps_.get_value(),
|
||||
property_download_speed_KBps_.get_value());
|
||||
renderer_.get_padding(xpad, ypad);
|
||||
|
||||
/* get the idealized cell dimensions */
|
||||
|
@ -451,27 +478,32 @@ void TorrentCellRenderer::Impl::get_size_compact(Gtk::Widget& widget, int& width
|
|||
*** LAYOUT
|
||||
**/
|
||||
|
||||
width = xpad * 2 + REQ_WIDTH(icon_size) + GUI_PAD + CompactBarWidth + GUI_PAD + REQ_WIDTH(stat_size);
|
||||
height = ypad * 2 + std::max(REQ_HEIGHT(name_size), bar_height.get_value());
|
||||
width = xpad * 2 + get_width(icon_size) + GUI_PAD + CompactBarWidth + GUI_PAD + get_width(stat_size);
|
||||
height = ypad * 2 + std::max(get_height(name_size), property_bar_height_.get_value());
|
||||
}
|
||||
|
||||
void TorrentCellRenderer::Impl::get_size_full(Gtk::Widget& widget, int& width, int& height) const
|
||||
{
|
||||
int xpad;
|
||||
int ypad;
|
||||
int xpad = 0;
|
||||
int ypad = 0;
|
||||
Gtk::Requisition min_size;
|
||||
Gtk::Requisition icon_size;
|
||||
Gtk::Requisition name_size;
|
||||
Gtk::Requisition stat_size;
|
||||
Gtk::Requisition prog_size;
|
||||
|
||||
auto* const tor = static_cast<tr_torrent*>(torrent.get_value());
|
||||
auto* const tor = static_cast<tr_torrent*>(property_torrent_.get_value());
|
||||
auto const* const st = tr_torrentStatCached(tor);
|
||||
auto const total_size = tr_torrentTotalSize(tor);
|
||||
|
||||
auto const icon = get_icon(tor);
|
||||
auto const name = Glib::ustring(tr_torrentName(tor));
|
||||
auto const gstr_stat = getStatusString(tor, st, upload_speed_KBps.get_value(), download_speed_KBps.get_value(), true);
|
||||
auto const gstr_stat = getStatusString(
|
||||
tor,
|
||||
st,
|
||||
property_upload_speed_KBps_.get_value(),
|
||||
property_download_speed_KBps_.get_value(),
|
||||
true);
|
||||
auto const gstr_prog = getProgressString(tor, total_size, st);
|
||||
renderer_.get_padding(xpad, ypad);
|
||||
|
||||
|
@ -494,19 +526,19 @@ void TorrentCellRenderer::Impl::get_size_full(Gtk::Widget& widget, int& width, i
|
|||
*** LAYOUT
|
||||
**/
|
||||
|
||||
width = xpad * 2 + REQ_WIDTH(icon_size) + GUI_PAD + std::max(REQ_WIDTH(prog_size), REQ_WIDTH(stat_size));
|
||||
height = ypad * 2 + REQ_HEIGHT(name_size) + REQ_HEIGHT(prog_size) + GUI_PAD_SMALL + bar_height.get_value() + GUI_PAD_SMALL +
|
||||
REQ_HEIGHT(stat_size);
|
||||
width = xpad * 2 + get_width(icon_size) + GUI_PAD + std::max(get_width(prog_size), get_width(stat_size));
|
||||
height = ypad * 2 + get_height(name_size) + get_height(prog_size) + GUI_PAD_SMALL + property_bar_height_.get_value() +
|
||||
GUI_PAD_SMALL + get_height(stat_size);
|
||||
}
|
||||
|
||||
void TorrentCellRenderer::get_preferred_width_vfunc(Gtk::Widget& widget, int& minimum_width, int& natural_width) const
|
||||
{
|
||||
if (impl_->torrent.get_value() != nullptr)
|
||||
if (impl_->property_torrent().get_value() != nullptr)
|
||||
{
|
||||
int w;
|
||||
int h;
|
||||
int w = 0;
|
||||
int h = 0;
|
||||
|
||||
if (impl_->compact.get_value())
|
||||
if (impl_->property_compact().get_value())
|
||||
{
|
||||
impl_->get_size_compact(widget, w, h);
|
||||
}
|
||||
|
@ -522,12 +554,12 @@ void TorrentCellRenderer::get_preferred_width_vfunc(Gtk::Widget& widget, int& mi
|
|||
|
||||
void TorrentCellRenderer::get_preferred_height_vfunc(Gtk::Widget& widget, int& minimum_height, int& natural_height) const
|
||||
{
|
||||
if (impl_->torrent.get_value() != nullptr)
|
||||
if (impl_->property_torrent().get_value() != nullptr)
|
||||
{
|
||||
int w;
|
||||
int h;
|
||||
int w = 0;
|
||||
int h = 0;
|
||||
|
||||
if (impl_->compact.get_value())
|
||||
if (impl_->property_compact().get_value())
|
||||
{
|
||||
impl_->get_size_compact(widget, w, h);
|
||||
}
|
||||
|
@ -544,22 +576,10 @@ void TorrentCellRenderer::get_preferred_height_vfunc(Gtk::Widget& widget, int& m
|
|||
namespace
|
||||
{
|
||||
|
||||
double get_percent_done(tr_torrent const* tor, tr_stat const* st, bool* seed)
|
||||
int get_percent_done(tr_torrent const* tor, tr_stat const* st)
|
||||
{
|
||||
double d;
|
||||
|
||||
if (st->activity == TR_STATUS_SEED && tr_torrentGetSeedRatio(tor, &d))
|
||||
{
|
||||
*seed = true;
|
||||
d = MAX(0.0, st->seedRatioPercentDone);
|
||||
}
|
||||
else
|
||||
{
|
||||
*seed = false;
|
||||
d = MAX(0.0, st->percentDone);
|
||||
}
|
||||
|
||||
return d;
|
||||
auto const seed = st->activity == TR_STATUS_SEED && tr_torrentGetSeedRatio(tor, nullptr);
|
||||
return static_cast<int>(seed ? std::max(0.0F, st->seedRatioPercentDone) : std::max(0.0F, st->percentDone));
|
||||
}
|
||||
|
||||
Gdk::RGBA const& get_progress_bar_color(tr_stat const& st)
|
||||
|
@ -683,17 +703,16 @@ void TorrentCellRenderer::Impl::render_compact(
|
|||
Gdk::Rectangle const& background_area,
|
||||
Gtk::CellRendererState flags)
|
||||
{
|
||||
int xpad;
|
||||
int ypad;
|
||||
int min_width;
|
||||
int width;
|
||||
bool seed;
|
||||
int xpad = 0;
|
||||
int ypad = 0;
|
||||
int min_width = 0;
|
||||
int width = 0;
|
||||
|
||||
auto* const tor = static_cast<tr_torrent*>(torrent.get_value());
|
||||
auto* const tor = static_cast<tr_torrent*>(property_torrent_.get_value());
|
||||
auto const* const st = tr_torrentStatCached(tor);
|
||||
bool const active = st->activity != TR_STATUS_STOPPED && st->activity != TR_STATUS_DOWNLOAD_WAIT &&
|
||||
st->activity != TR_STATUS_SEED_WAIT;
|
||||
auto const percentDone = get_percent_done(tor, st, &seed);
|
||||
auto const percent_done = get_percent_done(tor, st);
|
||||
bool const sensitive = active || st->error != 0;
|
||||
|
||||
if (st->activity == TR_STATUS_STOPPED)
|
||||
|
@ -713,7 +732,11 @@ void TorrentCellRenderer::Impl::render_compact(
|
|||
auto const icon = get_icon(tor);
|
||||
auto const name = Glib::ustring(tr_torrentName(tor));
|
||||
auto const& progress_color = get_progress_bar_color(*st);
|
||||
auto const gstr_stat = getShortStatusString(tor, st, upload_speed_KBps.get_value(), download_speed_KBps.get_value());
|
||||
auto const gstr_stat = getShortStatusString(
|
||||
tor,
|
||||
st,
|
||||
property_upload_speed_KBps_.get_value(),
|
||||
property_download_speed_KBps_.get_value());
|
||||
renderer_.get_padding(xpad, ypad);
|
||||
|
||||
auto fill_area = background_area;
|
||||
|
@ -764,7 +787,6 @@ void TorrentCellRenderer::Impl::render_compact(
|
|||
icon_renderer_->property_sensitive() = sensitive;
|
||||
render_impl(*icon_renderer_, snapshot, widget, icon_area, icon_area, flags);
|
||||
|
||||
auto const percent_done = static_cast<int>(percentDone * 100.0);
|
||||
progress_renderer_->property_value() = percent_done;
|
||||
progress_renderer_->property_text() = fmt::format(FMT_STRING("{:d}%"), percent_done);
|
||||
progress_renderer_->property_sensitive() = sensitive;
|
||||
|
@ -786,18 +808,17 @@ void TorrentCellRenderer::Impl::render_full(
|
|||
Gdk::Rectangle const& background_area,
|
||||
Gtk::CellRendererState flags)
|
||||
{
|
||||
int xpad;
|
||||
int ypad;
|
||||
int xpad = 0;
|
||||
int ypad = 0;
|
||||
Gtk::Requisition min_size;
|
||||
Gtk::Requisition size;
|
||||
bool seed;
|
||||
|
||||
auto* const tor = static_cast<tr_torrent*>(torrent.get_value());
|
||||
auto* const tor = static_cast<tr_torrent*>(property_torrent_.get_value());
|
||||
auto const* const st = tr_torrentStatCached(tor);
|
||||
auto const total_size = tr_torrentTotalSize(tor);
|
||||
bool const active = st->activity != TR_STATUS_STOPPED && st->activity != TR_STATUS_DOWNLOAD_WAIT &&
|
||||
st->activity != TR_STATUS_SEED_WAIT;
|
||||
auto const percentDone = get_percent_done(tor, st, &seed);
|
||||
auto const percent_done = get_percent_done(tor, st);
|
||||
bool const sensitive = active || st->error != 0;
|
||||
|
||||
if (st->activity == TR_STATUS_STOPPED)
|
||||
|
@ -818,15 +839,19 @@ void TorrentCellRenderer::Impl::render_full(
|
|||
auto const name = Glib::ustring(tr_torrentName(tor));
|
||||
auto const& progress_color = get_progress_bar_color(*st);
|
||||
auto const gstr_prog = getProgressString(tor, total_size, st);
|
||||
auto const gstr_stat = getStatusString(tor, st, upload_speed_KBps.get_value(), download_speed_KBps.get_value());
|
||||
auto const gstr_stat = getStatusString(
|
||||
tor,
|
||||
st,
|
||||
property_upload_speed_KBps_.get_value(),
|
||||
property_download_speed_KBps_.get_value());
|
||||
renderer_.get_padding(xpad, ypad);
|
||||
|
||||
/* get the idealized cell dimensions */
|
||||
Gdk::Rectangle icon_area;
|
||||
set_icon(*icon_renderer_, icon, FullIconSize);
|
||||
icon_renderer_->get_preferred_size(widget, min_size, size);
|
||||
icon_area.set_width(REQ_WIDTH(size));
|
||||
icon_area.set_height(REQ_HEIGHT(size));
|
||||
icon_area.set_width(get_width(size));
|
||||
icon_area.set_height(get_height(size));
|
||||
|
||||
Gdk::Rectangle name_area;
|
||||
text_renderer_->property_text() = name;
|
||||
|
@ -834,19 +859,19 @@ void TorrentCellRenderer::Impl::render_full(
|
|||
text_renderer_->property_ellipsize() = TR_PANGO_ELLIPSIZE_MODE(NONE);
|
||||
text_renderer_->property_scale() = 1.0;
|
||||
text_renderer_->get_preferred_size(widget, min_size, size);
|
||||
name_area.set_height(REQ_HEIGHT(size));
|
||||
name_area.set_height(get_height(size));
|
||||
|
||||
Gdk::Rectangle prog_area;
|
||||
text_renderer_->property_text() = gstr_prog;
|
||||
text_renderer_->property_weight() = TR_PANGO_WEIGHT(NORMAL);
|
||||
text_renderer_->property_scale() = SmallScale;
|
||||
text_renderer_->get_preferred_size(widget, min_size, size);
|
||||
prog_area.set_height(REQ_HEIGHT(size));
|
||||
prog_area.set_height(get_height(size));
|
||||
|
||||
Gdk::Rectangle stat_area;
|
||||
text_renderer_->property_text() = gstr_stat;
|
||||
text_renderer_->get_preferred_size(widget, min_size, size);
|
||||
stat_area.set_height(REQ_HEIGHT(size));
|
||||
stat_area.set_height(get_height(size));
|
||||
|
||||
Gdk::Rectangle prct_area;
|
||||
|
||||
|
@ -887,7 +912,7 @@ void TorrentCellRenderer::Impl::render_full(
|
|||
prct_area.set_x(prog_area.get_x());
|
||||
prct_area.set_y(prog_area.get_y() + prog_area.get_height() + GUI_PAD_SMALL);
|
||||
prct_area.set_width(prog_area.get_width());
|
||||
prct_area.set_height(bar_height.get_value());
|
||||
prct_area.set_height(property_bar_height_.get_value());
|
||||
|
||||
/* status */
|
||||
stat_area.set_x(prct_area.get_x());
|
||||
|
@ -913,7 +938,7 @@ void TorrentCellRenderer::Impl::render_full(
|
|||
text_renderer_->property_weight() = TR_PANGO_WEIGHT(NORMAL);
|
||||
render_impl(*text_renderer_, snapshot, widget, prog_area, prog_area, flags);
|
||||
|
||||
progress_renderer_->property_value() = static_cast<int>(percentDone * 100.0);
|
||||
progress_renderer_->property_value() = percent_done;
|
||||
progress_renderer_->property_text() = Glib::ustring();
|
||||
progress_renderer_->property_sensitive() = sensitive;
|
||||
render_progress_bar(snapshot, widget, prct_area, flags, progress_color);
|
||||
|
@ -934,9 +959,9 @@ void TorrentCellRenderer::IF_GTKMM4(snapshot_vfunc, render_vfunc)(
|
|||
widget.set_direction(Gtk::TEXT_DIR_RTL);
|
||||
#endif
|
||||
|
||||
if (impl_->torrent.get_value() != nullptr)
|
||||
if (impl_->property_torrent().get_value() != nullptr)
|
||||
{
|
||||
if (impl_->compact.get_value())
|
||||
if (impl_->property_compact().get_value())
|
||||
{
|
||||
impl_->render_compact(snapshot, widget, background_area, flags);
|
||||
}
|
||||
|
@ -967,42 +992,41 @@ TorrentCellRenderer::TorrentCellRenderer()
|
|||
TorrentCellRenderer::~TorrentCellRenderer() = default;
|
||||
|
||||
TorrentCellRenderer::Impl::Impl(TorrentCellRenderer& renderer)
|
||||
: torrent(renderer, "torrent", nullptr)
|
||||
, bar_height(renderer, "bar-height", DefaultBarHeight)
|
||||
, upload_speed_KBps(renderer, "piece-upload-speed", 0)
|
||||
, download_speed_KBps(renderer, "piece-download-speed", 0)
|
||||
, compact(renderer, "compact", false)
|
||||
, renderer_(renderer)
|
||||
: renderer_(renderer)
|
||||
, property_torrent_(renderer, "torrent", nullptr)
|
||||
, property_bar_height_(renderer, "bar-height", DefaultBarHeight)
|
||||
, property_upload_speed_KBps_(renderer, "piece-upload-speed", 0)
|
||||
, property_download_speed_KBps_(renderer, "piece-download-speed", 0)
|
||||
, property_compact_(renderer, "compact", false)
|
||||
, text_renderer_(Gtk::make_managed<Gtk::CellRendererText>())
|
||||
, progress_renderer_(Gtk::make_managed<Gtk::CellRendererProgress>())
|
||||
, icon_renderer_(Gtk::make_managed<Gtk::CellRendererPixbuf>())
|
||||
{
|
||||
text_renderer_ = Gtk::make_managed<Gtk::CellRendererText>();
|
||||
text_renderer_->property_xpad() = 0;
|
||||
text_renderer_->property_ypad() = 0;
|
||||
|
||||
progress_renderer_ = Gtk::make_managed<Gtk::CellRendererProgress>();
|
||||
icon_renderer_ = Gtk::make_managed<Gtk::CellRendererPixbuf>();
|
||||
}
|
||||
|
||||
Glib::PropertyProxy<gpointer> TorrentCellRenderer::property_torrent()
|
||||
{
|
||||
return impl_->torrent.get_proxy();
|
||||
return impl_->property_torrent().get_proxy();
|
||||
}
|
||||
|
||||
Glib::PropertyProxy<double> TorrentCellRenderer::property_piece_upload_speed()
|
||||
{
|
||||
return impl_->upload_speed_KBps.get_proxy();
|
||||
return impl_->property_upload_speed_KBps().get_proxy();
|
||||
}
|
||||
|
||||
Glib::PropertyProxy<double> TorrentCellRenderer::property_piece_download_speed()
|
||||
{
|
||||
return impl_->download_speed_KBps.get_proxy();
|
||||
return impl_->property_download_speed_KBps().get_proxy();
|
||||
}
|
||||
|
||||
Glib::PropertyProxy<int> TorrentCellRenderer::property_bar_height()
|
||||
{
|
||||
return impl_->bar_height.get_proxy();
|
||||
return impl_->property_bar_height().get_proxy();
|
||||
}
|
||||
|
||||
Glib::PropertyProxy<bool> TorrentCellRenderer::property_compact()
|
||||
{
|
||||
return impl_->compact.get_proxy();
|
||||
return impl_->property_compact().get_proxy();
|
||||
}
|
||||
|
|
|
@ -27,8 +27,16 @@ public:
|
|||
TR_DISABLE_COPY_MOVE(TorrentCellRenderer)
|
||||
|
||||
Glib::PropertyProxy<gpointer> property_torrent();
|
||||
|
||||
/* Use this instead of tr_stat.pieceUploadSpeed so that the model can
|
||||
control when the speed displays get updated. This is done to keep
|
||||
the individual torrents' speeds and the status bar's overall speed
|
||||
in sync even if they refresh at slightly different times */
|
||||
Glib::PropertyProxy<double> property_piece_upload_speed();
|
||||
|
||||
/* @see property_piece_upload_speed */
|
||||
Glib::PropertyProxy<double> property_piece_download_speed();
|
||||
|
||||
Glib::PropertyProxy<int> property_bar_height();
|
||||
Glib::PropertyProxy<bool> property_compact();
|
||||
|
||||
|
|
92
gtk/Utils.cc
92
gtk/Utils.cc
|
@ -6,6 +6,7 @@
|
|||
#include <array>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <stdexcept>
|
||||
#include <utility>
|
||||
|
||||
#include <giomm.h> /* g_file_trash() */
|
||||
|
@ -60,6 +61,28 @@ char const* const speed_T_str = N_("TB/s");
|
|||
****
|
||||
***/
|
||||
|
||||
void gtr_message(std::string const& message)
|
||||
{
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg)
|
||||
g_message("%s", message.c_str());
|
||||
}
|
||||
|
||||
void gtr_warning(std::string const& message)
|
||||
{
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg)
|
||||
g_warning("%s", message.c_str());
|
||||
}
|
||||
|
||||
void gtr_error(std::string const& message)
|
||||
{
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg)
|
||||
g_error("%s", message.c_str());
|
||||
}
|
||||
|
||||
/***
|
||||
****
|
||||
***/
|
||||
|
||||
Glib::ustring gtr_get_unicode_string(GtrUnicode uni)
|
||||
{
|
||||
switch (uni)
|
||||
|
@ -223,30 +246,9 @@ std::string tr_format_time_relative(time_t timestamp, time_t origin)
|
|||
return timestamp < origin ? tr_format_future_time(origin - timestamp) : tr_format_past_time(timestamp - origin);
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
Gtk::Window* getWindow(Gtk::Widget* w)
|
||||
{
|
||||
if (w == nullptr)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (auto* const window = dynamic_cast<Gtk::Window*>(w); window != nullptr)
|
||||
{
|
||||
return window;
|
||||
}
|
||||
|
||||
return static_cast<Gtk::Window*>(w->get_ancestor(Gtk::Window::get_type()));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void gtr_add_torrent_error_dialog(Gtk::Widget& child, tr_torrent* duplicate_torrent, std::string const& filename)
|
||||
{
|
||||
Glib::ustring secondary;
|
||||
auto* win = getWindow(&child);
|
||||
|
||||
if (duplicate_torrent != nullptr)
|
||||
{
|
||||
|
@ -261,7 +263,7 @@ void gtr_add_torrent_error_dialog(Gtk::Widget& child, tr_torrent* duplicate_torr
|
|||
}
|
||||
|
||||
auto w = std::make_shared<Gtk::MessageDialog>(
|
||||
*win,
|
||||
gtr_widget_get_window(child),
|
||||
_("Couldn't open torrent"),
|
||||
false,
|
||||
TR_GTK_MESSAGE_TYPE(ERROR),
|
||||
|
@ -390,14 +392,11 @@ bool gtr_file_trash_or_remove(std::string const& filename, tr_error** error)
|
|||
}
|
||||
catch (Glib::Error const& e)
|
||||
{
|
||||
g_message(
|
||||
"%s",
|
||||
fmt::format(
|
||||
_("Couldn't move '{path}' to trash: {error} ({error_code})"),
|
||||
fmt::arg("path", filename),
|
||||
fmt::arg("error", TR_GLIB_EXCEPTION_WHAT(e)),
|
||||
fmt::arg("error_code", e.code()))
|
||||
.c_str());
|
||||
gtr_message(fmt::format(
|
||||
_("Couldn't move '{path}' to trash: {error} ({error_code})"),
|
||||
fmt::arg("path", filename),
|
||||
fmt::arg("error", TR_GLIB_EXCEPTION_WHAT(e)),
|
||||
fmt::arg("error_code", e.code())));
|
||||
tr_error_set(error, e.code(), TR_GLIB_EXCEPTION_WHAT(e));
|
||||
}
|
||||
}
|
||||
|
@ -410,14 +409,11 @@ bool gtr_file_trash_or_remove(std::string const& filename, tr_error** error)
|
|||
}
|
||||
catch (Glib::Error const& e)
|
||||
{
|
||||
g_message(
|
||||
"%s",
|
||||
fmt::format(
|
||||
_("Couldn't remove '{path}': {error} ({error_code})"),
|
||||
fmt::arg("path", filename),
|
||||
fmt::arg("error", TR_GLIB_EXCEPTION_WHAT(e)),
|
||||
fmt::arg("error_code", e.code()))
|
||||
.c_str());
|
||||
gtr_message(fmt::format(
|
||||
_("Couldn't remove '{path}': {error} ({error_code})"),
|
||||
fmt::arg("path", filename),
|
||||
fmt::arg("error", TR_GLIB_EXCEPTION_WHAT(e)),
|
||||
fmt::arg("error_code", e.code())));
|
||||
tr_error_clear(error);
|
||||
tr_error_set(error, e.code(), TR_GLIB_EXCEPTION_WHAT(e));
|
||||
result = false;
|
||||
|
@ -469,7 +465,7 @@ void gtr_open_uri(Glib::ustring const& uri)
|
|||
|
||||
if (!opened)
|
||||
{
|
||||
g_message("%s", fmt::format(_("Couldn't open '{url}'"), fmt::arg("url", uri)).c_str());
|
||||
gtr_message(fmt::format(_("Couldn't open '{url}'"), fmt::arg("url", uri)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -630,6 +626,20 @@ void gtr_widget_set_visible(Gtk::Widget& w, bool b)
|
|||
w.set_visible(b);
|
||||
}
|
||||
|
||||
Gtk::Window& gtr_widget_get_window(Gtk::Widget& widget)
|
||||
{
|
||||
if (auto* const window = dynamic_cast<Gtk::Window*>(TR_GTK_WIDGET_GET_ROOT(widget)); window != nullptr)
|
||||
{
|
||||
return *window;
|
||||
}
|
||||
|
||||
#if defined(G_DISABLE_ASSERT)
|
||||
throw std::logic_error("Supplied widget doesn't have a window");
|
||||
#else
|
||||
g_assert_not_reached();
|
||||
#endif
|
||||
}
|
||||
|
||||
void gtr_window_set_skip_taskbar_hint([[maybe_unused]] Gtk::Window& window, [[maybe_unused]] bool value)
|
||||
{
|
||||
#if GTK_CHECK_VERSION(4, 0, 0)
|
||||
|
@ -671,12 +681,10 @@ void gtr_window_raise([[maybe_unused]] Gtk::Window& window)
|
|||
|
||||
void gtr_unrecognized_url_dialog(Gtk::Widget& parent, Glib::ustring const& url)
|
||||
{
|
||||
auto* window = getWindow(&parent);
|
||||
|
||||
Glib::ustring gstr;
|
||||
|
||||
auto w = std::make_shared<Gtk::MessageDialog>(
|
||||
*window,
|
||||
gtr_widget_get_window(parent),
|
||||
fmt::format(_("Unsupported URL: '{url}'"), fmt::arg("url", url)),
|
||||
false /*use markup*/,
|
||||
TR_GTK_MESSAGE_TYPE(ERROR),
|
||||
|
|
14
gtk/Utils.h
14
gtk/Utils.h
|
@ -130,6 +130,18 @@ 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_warning(std::string const& message);
|
||||
void gtr_error(std::string const& message);
|
||||
|
||||
/***
|
||||
****
|
||||
***/
|
||||
|
||||
enum class GtrUnicode
|
||||
{
|
||||
Up,
|
||||
|
@ -167,6 +179,8 @@ Glib::ustring gtr_get_help_uri();
|
|||
/* backwards-compatible wrapper around gtk_widget_set_visible() */
|
||||
void gtr_widget_set_visible(Gtk::Widget&, bool);
|
||||
|
||||
Gtk::Window& gtr_widget_get_window(Gtk::Widget& widget);
|
||||
|
||||
void gtr_window_set_skip_taskbar_hint(Gtk::Window& window, bool value);
|
||||
void gtr_window_set_urgency_hint(Gtk::Window& window, bool value);
|
||||
void gtr_window_raise(Gtk::Window& window);
|
||||
|
|
|
@ -55,7 +55,7 @@ int main(int argc, char** argv)
|
|||
Gio::File::create_for_path(".");
|
||||
Glib::wrap_register(
|
||||
g_type_from_name("GLocalFile"),
|
||||
[](GObject* object) -> Glib::ObjectBase* { return new Gio::File((GFile*)object); });
|
||||
[](GObject* object) -> Glib::ObjectBase* { return new Gio::File(G_FILE(object)); });
|
||||
g_type_ensure(Gio::File::get_type());
|
||||
|
||||
/* default settings */
|
||||
|
@ -93,7 +93,7 @@ int main(int argc, char** argv)
|
|||
fmt::print(
|
||||
stderr,
|
||||
_("Run '{program} --help' to see a full list of available command line options.\n"),
|
||||
fmt::arg("program", argv[0]));
|
||||
fmt::arg("program", *argv));
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue