Switch to Gtk::Builder for all UI in GTK client (#3781)
* Move CSS definitions to resources * Add Gtk::Builder helpers * Switch StatsDialog to Gtk::Builder * Switch RelocateDialog to Gtk::Builder * Switch OptionsDialog to Gtk::Builder * Switch MakeDialog to Gtk::Builder * Switch FilterBar to Gtk::Builder * Switch MainWindow to Gtk::Builder * Switch MessageLogWindow to Gtk::Builder * Switch DetailsDialog to Gtk::Builder * Switch PrefsDialog to Gtk::Builder * Fixup translatable strings Since this branch was brewing for a while, changes happened in the meantime.
This commit is contained in:
parent
c000311b80
commit
b41501eeb8
|
@ -0,0 +1,130 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Generated with glade 3.38.2 -->
|
||||
<interface>
|
||||
<requires lib="gtk+" version="3.24"/>
|
||||
<object class="GtkDialog" id="AddTrackerDialog">
|
||||
<property name="can-focus">False</property>
|
||||
<property name="border-width">6</property>
|
||||
<property name="modal">True</property>
|
||||
<property name="type-hint">dialog</property>
|
||||
<child internal-child="vbox">
|
||||
<object class="GtkBox" id="dialog_layout">
|
||||
<property name="can-focus">False</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">6</property>
|
||||
<child internal-child="action_area">
|
||||
<object class="GtkButtonBox" id="dialog_buttons">
|
||||
<property name="can-focus">False</property>
|
||||
<property name="layout-style">end</property>
|
||||
<child>
|
||||
<object class="GtkButton" id="cancel_button">
|
||||
<property name="label" translatable="yes">_Cancel</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="receives-default">True</property>
|
||||
<property name="use-underline">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="open_button">
|
||||
<property name="label" translatable="yes">_Add</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="receives-default">True</property>
|
||||
<property name="use-underline">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox" id="dialog_content_layout">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">6</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="url_section_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="label" translatable="yes">Tracker</property>
|
||||
<property name="xalign">0</property>
|
||||
<attributes>
|
||||
<attribute name="weight" value="bold"/>
|
||||
</attributes>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<!-- n-columns=2 n-rows=1 -->
|
||||
<object class="GtkGrid" id="url_section_layout">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="margin-start">18</property>
|
||||
<property name="row-spacing">6</property>
|
||||
<property name="column-spacing">12</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="url_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="label" translatable="yes">_Announce URL:</property>
|
||||
<property name="use-underline">True</property>
|
||||
<property name="mnemonic-widget">url_entry</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkEntry" id="url_entry">
|
||||
<property name="width-request">400</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="hexpand">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">1</property>
|
||||
<property name="top-attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<action-widgets>
|
||||
<action-widget response="-6">cancel_button</action-widget>
|
||||
<action-widget response="-3">open_button</action-widget>
|
||||
</action-widgets>
|
||||
</object>
|
||||
</interface>
|
|
@ -5,12 +5,13 @@
|
|||
#include <algorithm>
|
||||
#include <cstdlib> // exit()
|
||||
#include <ctime>
|
||||
#include <iterator> // for std::back_inserter
|
||||
#include <iterator> // std::back_inserter
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <thread>
|
||||
#include <tuple>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
|
@ -34,7 +35,8 @@
|
|||
#include "Application.h"
|
||||
#include "DetailsDialog.h"
|
||||
#include "Dialogs.h"
|
||||
#include "HigWorkarea.h"
|
||||
#include "FilterBar.h"
|
||||
#include "HigWorkarea.h" // GUI_PAD, GUI_PAD_BIG
|
||||
#include "MainWindow.h"
|
||||
#include "MakeDialog.h"
|
||||
#include "MessageLogWindow.h"
|
||||
|
@ -535,6 +537,16 @@ void Application::Impl::on_startup()
|
|||
Gtk::IconTheme::get_default()->add_resource_path(gtr_get_full_resource_path("icons"s));
|
||||
Gtk::Window::set_default_icon_name(AppIconName);
|
||||
|
||||
/* Add style provider to the window. */
|
||||
auto css_provider = Gtk::CssProvider::create();
|
||||
css_provider->load_from_resource(gtr_get_full_resource_path("transmission-ui.css"));
|
||||
Gtk::StyleContext::add_provider_for_screen(
|
||||
Gdk::Screen::get_default(),
|
||||
css_provider,
|
||||
GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
|
||||
|
||||
std::ignore = FilterBar();
|
||||
|
||||
tr_session* session;
|
||||
|
||||
::signal(SIGINT, signal_handler);
|
||||
|
|
|
@ -20,6 +20,22 @@ endif()
|
|||
|
||||
find_program(APPSTREAM appstreamcli)
|
||||
|
||||
set(${PROJECT_NAME}_UI_FILES
|
||||
AddTrackerDialog.ui
|
||||
DetailsDialog.ui
|
||||
EditTrackersDialog.ui
|
||||
FilterBar.ui
|
||||
MainWindow.ui
|
||||
MakeDialog.ui
|
||||
MakeProgressDialog.ui
|
||||
MessageLogWindow.ui
|
||||
OptionsDialog.ui
|
||||
PrefsDialog.ui
|
||||
RelocateDialog.ui
|
||||
StatsDialog.ui
|
||||
TorrentUrlChooserDialog.ui
|
||||
)
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT
|
||||
${CMAKE_CURRENT_BINARY_DIR}/transmission-resources.c
|
||||
|
@ -46,6 +62,7 @@ add_custom_command(
|
|||
icons/turtle-symbolic.svg
|
||||
transmission-ui.xml
|
||||
transmission.gresource.xml
|
||||
${${PROJECT_NAME}_UI_FILES}
|
||||
WORKING_DIRECTORY
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
)
|
||||
|
|
|
@ -5,13 +5,13 @@
|
|||
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <limits.h> /* INT_MAX */
|
||||
#include <limits.h> // INT_MAX
|
||||
#include <memory>
|
||||
#include <numeric>
|
||||
#include <sstream>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h> /* sscanf() */
|
||||
#include <stdlib.h> /* abort() */
|
||||
#include <stdio.h> // sscanf()
|
||||
#include <stdlib.h> // abort()
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <unordered_map>
|
||||
|
@ -28,9 +28,9 @@
|
|||
|
||||
#include "Actions.h"
|
||||
#include "DetailsDialog.h"
|
||||
#include "FaviconCache.h" /* gtr_get_favicon() */
|
||||
#include "FaviconCache.h" // gtr_get_favicon()
|
||||
#include "FileList.h"
|
||||
#include "HigWorkarea.h"
|
||||
#include "HigWorkarea.h" // GUI_PAD, GUI_PAD_BIG, GUI_PAD_SMALL
|
||||
#include "Prefs.h"
|
||||
#include "PrefsDialog.h"
|
||||
#include "Session.h"
|
||||
|
@ -41,18 +41,19 @@ using namespace std::literals;
|
|||
class DetailsDialog::Impl
|
||||
{
|
||||
public:
|
||||
Impl(DetailsDialog& dialog, Glib::RefPtr<Session> const& core);
|
||||
Impl(DetailsDialog& dialog, Glib::RefPtr<Gtk::Builder> const& builder, Glib::RefPtr<Session> const& core);
|
||||
~Impl();
|
||||
|
||||
TR_DISABLE_COPY_MOVE(Impl)
|
||||
|
||||
void set_torrents(std::vector<tr_torrent_id_t> const& torrent_ids);
|
||||
void refresh();
|
||||
|
||||
private:
|
||||
Gtk::Widget* info_page_new();
|
||||
Gtk::Widget* peer_page_new();
|
||||
Gtk::Widget* tracker_page_new();
|
||||
Gtk::Widget* options_page_new();
|
||||
void info_page_init(Glib::RefPtr<Gtk::Builder> const& builder);
|
||||
void peer_page_init(Glib::RefPtr<Gtk::Builder> const& builder);
|
||||
void tracker_page_init(Glib::RefPtr<Gtk::Builder> const& builder);
|
||||
void options_page_init(Glib::RefPtr<Gtk::Builder> const& builder);
|
||||
|
||||
void on_details_window_size_allocated(Gtk::Allocation& alloc);
|
||||
|
||||
|
@ -68,15 +69,10 @@ private:
|
|||
void onScrapeToggled();
|
||||
void onBackupToggled();
|
||||
|
||||
void on_add_tracker_response(int response, std::shared_ptr<Gtk::Dialog>& dialog);
|
||||
void on_edit_trackers_response(int response, std::shared_ptr<Gtk::Dialog>& dialog);
|
||||
|
||||
void torrent_set_bool(tr_quark key, bool value);
|
||||
void torrent_set_int(tr_quark key, int value);
|
||||
void torrent_set_real(tr_quark key, double value);
|
||||
|
||||
void refresh();
|
||||
|
||||
void refreshInfo(std::vector<tr_torrent*> const& torrents);
|
||||
void refreshPeers(std::vector<tr_torrent*> const& torrents);
|
||||
void refreshTracker(std::vector<tr_torrent*> const& torrents);
|
||||
|
@ -92,6 +88,7 @@ private:
|
|||
|
||||
private:
|
||||
DetailsDialog& dialog_;
|
||||
Glib::RefPtr<Session> const core_;
|
||||
|
||||
Gtk::CheckButton* honor_limits_check_ = nullptr;
|
||||
Gtk::CheckButton* up_limited_check_ = nullptr;
|
||||
|
@ -157,7 +154,6 @@ private:
|
|||
Gtk::Label* file_label_ = nullptr;
|
||||
|
||||
std::vector<tr_torrent_id_t> ids_;
|
||||
Glib::RefPtr<Session> const core_;
|
||||
sigc::connection periodic_refresh_tag_;
|
||||
|
||||
Glib::Quark const TORRENT_ID_KEY = Glib::Quark("tr-torrent-id-key");
|
||||
|
@ -457,97 +453,69 @@ void DetailsDialog::Impl::torrent_set_real(tr_quark key, double value)
|
|||
tr_variantClear(&top);
|
||||
}
|
||||
|
||||
Gtk::Widget* DetailsDialog::Impl::options_page_new()
|
||||
void DetailsDialog::Impl::options_page_init(Glib::RefPtr<Gtk::Builder> const& /*builder*/)
|
||||
{
|
||||
guint row;
|
||||
|
||||
row = 0;
|
||||
auto* t = Gtk::make_managed<HigWorkarea>();
|
||||
t->add_section_title(row, _("Speed"));
|
||||
|
||||
honor_limits_check_ = t->add_wide_checkbutton(row, _("Honor global _limits"), false);
|
||||
honor_limits_check_tag_ = honor_limits_check_->signal_toggled().connect(
|
||||
[this]() { torrent_set_bool(TR_KEY_honorsSessionLimits, honor_limits_check_->get_active()); });
|
||||
|
||||
down_limited_check_ = Gtk::make_managed<Gtk::CheckButton>(
|
||||
fmt::format(_("Limit _download speed ({speed_units}):"), fmt::arg("speed_units", speed_K_str)),
|
||||
true);
|
||||
down_limited_check_->set_active(false);
|
||||
down_limited_check_->set_label(fmt::format(down_limited_check_->get_label().raw(), fmt::arg("speed_units", speed_K_str)));
|
||||
down_limited_check_tag_ = down_limited_check_->signal_toggled().connect(
|
||||
[this]() { torrent_set_bool(TR_KEY_downloadLimited, down_limited_check_->get_active()); });
|
||||
|
||||
down_limit_spin_ = Gtk::make_managed<Gtk::SpinButton>(Gtk::Adjustment::create(0, 0, INT_MAX, 5));
|
||||
down_limit_spin_->set_adjustment(Gtk::Adjustment::create(0, 0, INT_MAX, 5));
|
||||
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()); });
|
||||
t->add_row_w(row, *down_limited_check_, *down_limit_spin_);
|
||||
|
||||
up_limited_check_ = Gtk::make_managed<Gtk::CheckButton>(
|
||||
fmt::format(_("Limit _upload speed ({speed_units}):"), fmt::arg("speed_units", speed_K_str)),
|
||||
true);
|
||||
up_limited_check_->set_label(fmt::format(up_limited_check_->get_label().raw(), fmt::arg("speed_units", speed_K_str)));
|
||||
up_limited_check_tag_ = up_limited_check_->signal_toggled().connect(
|
||||
[this]() { torrent_set_bool(TR_KEY_uploadLimited, up_limited_check_->get_active()); });
|
||||
|
||||
up_limit_sping_ = Gtk::make_managed<Gtk::SpinButton>(Gtk::Adjustment::create(0, 0, INT_MAX, 5));
|
||||
up_limit_sping_->set_adjustment(Gtk::Adjustment::create(0, 0, INT_MAX, 5));
|
||||
up_limit_spin_tag_ = up_limit_sping_->signal_value_changed().connect(
|
||||
[this]() { torrent_set_int(TR_KEY_uploadLimit, up_limit_sping_->get_value_as_int()); });
|
||||
t->add_row_w(row, *up_limited_check_, *up_limit_sping_);
|
||||
|
||||
bandwidth_combo_ = gtr_priority_combo_new();
|
||||
gtr_priority_combo_init(*bandwidth_combo_);
|
||||
bandwidth_combo_tag_ = bandwidth_combo_->signal_changed().connect(
|
||||
[this]() { torrent_set_int(TR_KEY_bandwidthPriority, gtr_priority_combo_get_value(*bandwidth_combo_)); });
|
||||
t->add_row(row, _("Torrent _priority:"), *bandwidth_combo_);
|
||||
|
||||
t->add_section_divider(row);
|
||||
t->add_section_title(row, _("Seeding Limits"));
|
||||
|
||||
auto* h1 = Gtk::make_managed<Gtk::Box>(Gtk::ORIENTATION_HORIZONTAL, GUI_PAD);
|
||||
ratio_combo_ = gtr_combo_box_new_enum({
|
||||
{ _("Use global settings"), TR_RATIOLIMIT_GLOBAL },
|
||||
{ _("Seed regardless of ratio"), TR_RATIOLIMIT_UNLIMITED },
|
||||
{ _("Stop seeding at ratio:"), TR_RATIOLIMIT_SINGLE },
|
||||
});
|
||||
gtr_combo_box_set_enum(
|
||||
*ratio_combo_,
|
||||
{
|
||||
{ _("Use global settings"), TR_RATIOLIMIT_GLOBAL },
|
||||
{ _("Seed regardless of ratio"), TR_RATIOLIMIT_UNLIMITED },
|
||||
{ _("Stop seeding at ratio:"), TR_RATIOLIMIT_SINGLE },
|
||||
});
|
||||
ratio_combo_tag_ = ratio_combo_->signal_changed().connect(
|
||||
[this]()
|
||||
{
|
||||
torrent_set_int(TR_KEY_seedRatioMode, gtr_combo_box_get_active_enum(*ratio_combo_));
|
||||
refresh();
|
||||
});
|
||||
h1->pack_start(*ratio_combo_, true, true, 0);
|
||||
ratio_spin_ = Gtk::make_managed<Gtk::SpinButton>(Gtk::Adjustment::create(0, 0, 1000, .05));
|
||||
ratio_spin_->set_adjustment(Gtk::Adjustment::create(0, 0, 1000, .05));
|
||||
ratio_spin_->set_width_chars(7);
|
||||
ratio_spin_tag_ = ratio_spin_->signal_value_changed().connect(
|
||||
[this]() { torrent_set_real(TR_KEY_seedRatioLimit, ratio_spin_->get_value()); });
|
||||
h1->pack_start(*ratio_spin_, false, false, 0);
|
||||
t->add_row(row, _("_Ratio:"), *h1);
|
||||
|
||||
auto* h2 = Gtk::make_managed<Gtk::Box>(Gtk::ORIENTATION_HORIZONTAL, GUI_PAD);
|
||||
idle_combo_ = gtr_combo_box_new_enum({
|
||||
{ _("Use global settings"), TR_IDLELIMIT_GLOBAL },
|
||||
{ _("Seed regardless of activity"), TR_IDLELIMIT_UNLIMITED },
|
||||
{ _("Stop seeding if idle for N minutes:"), TR_IDLELIMIT_SINGLE },
|
||||
});
|
||||
gtr_combo_box_set_enum(
|
||||
*idle_combo_,
|
||||
{
|
||||
{ _("Use global settings"), TR_IDLELIMIT_GLOBAL },
|
||||
{ _("Seed regardless of activity"), TR_IDLELIMIT_UNLIMITED },
|
||||
{ _("Stop seeding if idle for N minutes:"), TR_IDLELIMIT_SINGLE },
|
||||
});
|
||||
idle_combo_tag_ = idle_combo_->signal_changed().connect(
|
||||
[this]()
|
||||
{
|
||||
torrent_set_int(TR_KEY_seedIdleMode, gtr_combo_box_get_active_enum(*idle_combo_));
|
||||
refresh();
|
||||
});
|
||||
h2->pack_start(*idle_combo_, true, true, 0);
|
||||
idle_spin_ = Gtk::make_managed<Gtk::SpinButton>(Gtk::Adjustment::create(1, 1, 40320, 5));
|
||||
idle_spin_->set_adjustment(Gtk::Adjustment::create(1, 1, 40320, 5));
|
||||
idle_spin_tag_ = idle_spin_->signal_value_changed().connect(
|
||||
[this]() { torrent_set_int(TR_KEY_seedIdleLimit, idle_spin_->get_value_as_int()); });
|
||||
h2->pack_start(*idle_spin_, false, false, 0);
|
||||
t->add_row(row, _("_Idle:"), *h2);
|
||||
|
||||
t->add_section_divider(row);
|
||||
t->add_section_title(row, _("Peer Connections"));
|
||||
|
||||
max_peers_spin_ = Gtk::make_managed<Gtk::SpinButton>(Gtk::Adjustment::create(1, 1, 3000, 5));
|
||||
t->add_row(row, _("_Maximum peers:"), *max_peers_spin_, max_peers_spin_);
|
||||
max_peers_spin_->set_adjustment(Gtk::Adjustment::create(1, 1, 3000, 5));
|
||||
max_peers_spin_tag_ = max_peers_spin_->signal_value_changed().connect(
|
||||
[this]() { torrent_set_int(TR_KEY_peer_limit, max_peers_spin_->get_value_as_int()); });
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
/****
|
||||
|
@ -1084,111 +1052,11 @@ void DetailsDialog::Impl::refreshInfo(std::vector<tr_torrent*> const& torrents)
|
|||
last_activity_lb_->set_text(str);
|
||||
}
|
||||
|
||||
Gtk::Widget* DetailsDialog::Impl::info_page_new()
|
||||
void DetailsDialog::Impl::info_page_init(Glib::RefPtr<Gtk::Builder> const& builder)
|
||||
{
|
||||
guint row = 0;
|
||||
auto* t = Gtk::make_managed<HigWorkarea>();
|
||||
|
||||
t->add_section_title(row, _("Activity"));
|
||||
|
||||
/* size */
|
||||
size_lb_ = Gtk::make_managed<Gtk::Label>();
|
||||
size_lb_->set_single_line_mode(true);
|
||||
t->add_row(row, _("Torrent size:"), *size_lb_);
|
||||
|
||||
/* have */
|
||||
have_lb_ = Gtk::make_managed<Gtk::Label>();
|
||||
have_lb_->set_single_line_mode(true);
|
||||
t->add_row(row, _("Have:"), *have_lb_);
|
||||
|
||||
/* uploaded */
|
||||
ul_lb_ = Gtk::make_managed<Gtk::Label>();
|
||||
ul_lb_->set_single_line_mode(true);
|
||||
t->add_row(row, _("Uploaded:"), *ul_lb_);
|
||||
|
||||
/* downloaded */
|
||||
dl_lb_ = Gtk::make_managed<Gtk::Label>();
|
||||
dl_lb_->set_single_line_mode(true);
|
||||
t->add_row(row, _("Downloaded:"), *dl_lb_);
|
||||
|
||||
/* state */
|
||||
state_lb_ = Gtk::make_managed<Gtk::Label>();
|
||||
state_lb_->set_single_line_mode(true);
|
||||
t->add_row(row, _("State:"), *state_lb_);
|
||||
|
||||
/* running for */
|
||||
date_started_lb_ = Gtk::make_managed<Gtk::Label>();
|
||||
date_started_lb_->set_single_line_mode(true);
|
||||
t->add_row(row, _("Running time:"), *date_started_lb_);
|
||||
|
||||
/* eta */
|
||||
eta_lb_ = Gtk::make_managed<Gtk::Label>();
|
||||
eta_lb_->set_single_line_mode(true);
|
||||
t->add_row(row, _("Remaining time:"), *eta_lb_);
|
||||
|
||||
/* last activity */
|
||||
last_activity_lb_ = Gtk::make_managed<Gtk::Label>();
|
||||
last_activity_lb_->set_single_line_mode(true);
|
||||
t->add_row(row, _("Last activity:"), *last_activity_lb_);
|
||||
|
||||
/* error */
|
||||
error_lb_ = Gtk::make_managed<Gtk::Label>();
|
||||
error_lb_->set_selectable(true);
|
||||
error_lb_->set_ellipsize(Pango::ELLIPSIZE_END);
|
||||
error_lb_->set_line_wrap(true);
|
||||
error_lb_->set_lines(10);
|
||||
t->add_row(row, _("Error:"), *error_lb_);
|
||||
|
||||
/* details */
|
||||
t->add_section_divider(row);
|
||||
t->add_section_title(row, _("Details"));
|
||||
|
||||
/* destination */
|
||||
destination_lb_ = Gtk::make_managed<Gtk::Label>();
|
||||
destination_lb_->set_selectable(true);
|
||||
destination_lb_->set_ellipsize(Pango::ELLIPSIZE_END);
|
||||
t->add_row(row, _("Location:"), *destination_lb_);
|
||||
|
||||
/* hash */
|
||||
hash_lb_ = Gtk::make_managed<Gtk::Label>();
|
||||
hash_lb_->set_selectable(true);
|
||||
hash_lb_->set_ellipsize(Pango::ELLIPSIZE_END);
|
||||
t->add_row(row, _("Hash:"), *hash_lb_);
|
||||
|
||||
/* privacy */
|
||||
privacy_lb_ = Gtk::make_managed<Gtk::Label>();
|
||||
privacy_lb_->set_single_line_mode(true);
|
||||
t->add_row(row, _("Privacy:"), *privacy_lb_);
|
||||
|
||||
/* origins */
|
||||
origin_lb_ = Gtk::make_managed<Gtk::Label>();
|
||||
origin_lb_->set_selectable(true);
|
||||
origin_lb_->set_ellipsize(Pango::ELLIPSIZE_END);
|
||||
t->add_row(row, _("Origin:"), *origin_lb_);
|
||||
|
||||
/* added */
|
||||
added_lb_ = Gtk::make_managed<Gtk::Label>();
|
||||
added_lb_->set_single_line_mode(true);
|
||||
t->add_row(row, _("Added:"), *added_lb_);
|
||||
|
||||
/* comment */
|
||||
comment_buffer_ = Gtk::TextBuffer::create();
|
||||
auto* tw = Gtk::make_managed<Gtk::TextView>(comment_buffer_);
|
||||
tw->set_wrap_mode(Gtk::WRAP_WORD);
|
||||
tw->set_editable(false);
|
||||
auto* sw = Gtk::make_managed<Gtk::ScrolledWindow>();
|
||||
sw->set_size_request(350, 36);
|
||||
sw->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
|
||||
sw->add(*tw);
|
||||
auto* fr = Gtk::make_managed<Gtk::Frame>();
|
||||
fr->set_shadow_type(Gtk::SHADOW_IN);
|
||||
fr->add(*sw);
|
||||
auto* w = t->add_tall_row(row, _("Comment:"), *fr);
|
||||
w->set_halign(Gtk::ALIGN_START);
|
||||
w->set_valign(Gtk::ALIGN_START);
|
||||
|
||||
t->add_section_divider(row);
|
||||
return t;
|
||||
auto* tw = gtr_get_widget<Gtk::TextView>(builder, "comment_value_view");
|
||||
tw->set_buffer(comment_buffer_);
|
||||
}
|
||||
|
||||
/****
|
||||
|
@ -1823,12 +1691,13 @@ void DetailsDialog::Impl::onMorePeerInfoToggled()
|
|||
setPeerViewColumns(peer_view_);
|
||||
}
|
||||
|
||||
Gtk::Widget* DetailsDialog::Impl::peer_page_new()
|
||||
void DetailsDialog::Impl::peer_page_init(Glib::RefPtr<Gtk::Builder> const& builder)
|
||||
{
|
||||
/* webseeds */
|
||||
|
||||
webseed_store_ = Gtk::ListStore::create(webseed_cols);
|
||||
auto* v = Gtk::make_managed<Gtk::TreeView>(webseed_store_);
|
||||
auto* v = gtr_get_widget<Gtk::TreeView>(builder, "webseeds_view");
|
||||
v->set_model(webseed_store_);
|
||||
v->signal_button_release_event().connect([v](GdkEventButton* event) { return on_tree_view_button_released(v, event); });
|
||||
|
||||
{
|
||||
|
@ -1849,44 +1718,22 @@ Gtk::Widget* DetailsDialog::Impl::peer_page_new()
|
|||
v->append_column(*c);
|
||||
}
|
||||
|
||||
webseed_view_ = Gtk::make_managed<Gtk::ScrolledWindow>();
|
||||
webseed_view_->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
|
||||
webseed_view_->set_shadow_type(Gtk::SHADOW_IN);
|
||||
webseed_view_->add(*v);
|
||||
|
||||
/* peers */
|
||||
|
||||
peer_store_ = Gtk::ListStore::create(peer_cols);
|
||||
auto m = Gtk::TreeModelSort::create(peer_store_);
|
||||
m->set_sort_column(peer_cols.progress, Gtk::SORT_DESCENDING);
|
||||
peer_view_ = Gtk::make_managed<Gtk::TreeView>(m);
|
||||
peer_view_->set_has_tooltip(true);
|
||||
|
||||
peer_view_->set_model(m);
|
||||
peer_view_->set_has_tooltip(true);
|
||||
peer_view_->signal_query_tooltip().connect(sigc::mem_fun(*this, &Impl::onPeerViewQueryTooltip));
|
||||
peer_view_->signal_button_release_event().connect([this](GdkEventButton* event)
|
||||
{ return on_tree_view_button_released(peer_view_, event); });
|
||||
|
||||
setPeerViewColumns(peer_view_);
|
||||
|
||||
auto* sw = Gtk::make_managed<Gtk::ScrolledWindow>();
|
||||
sw->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
|
||||
sw->set_shadow_type(Gtk::SHADOW_IN);
|
||||
sw->add(*peer_view_);
|
||||
|
||||
auto* vbox = Gtk::make_managed<Gtk::Box>(Gtk::ORIENTATION_VERTICAL, GUI_PAD);
|
||||
vbox->set_border_width(GUI_PAD_BIG);
|
||||
|
||||
auto* v2 = Gtk::make_managed<Gtk::Paned>(Gtk::ORIENTATION_VERTICAL);
|
||||
v2->add(*webseed_view_);
|
||||
v2->add(*sw);
|
||||
vbox->pack_start(*v2, true, true);
|
||||
|
||||
more_peer_details_check_ = Gtk::make_managed<Gtk::CheckButton>(_("Show _more details"), true);
|
||||
more_peer_details_check_->set_active(gtr_pref_flag_get(TR_KEY_show_extra_peer_details));
|
||||
more_peer_details_check_->signal_toggled().connect(sigc::mem_fun(*this, &Impl::onMorePeerInfoToggled));
|
||||
vbox->pack_start(*more_peer_details_check_, false, false);
|
||||
|
||||
return vbox;
|
||||
}
|
||||
|
||||
/****
|
||||
|
@ -2267,25 +2114,81 @@ void DetailsDialog::Impl::onBackupToggled()
|
|||
refresh();
|
||||
}
|
||||
|
||||
void DetailsDialog::Impl::on_edit_trackers_response(int response, std::shared_ptr<Gtk::Dialog>& dialog)
|
||||
namespace
|
||||
{
|
||||
|
||||
class EditTrackersDialog : public Gtk::Dialog
|
||||
{
|
||||
public:
|
||||
EditTrackersDialog(
|
||||
BaseObjectType* cast_item,
|
||||
Glib::RefPtr<Gtk::Builder> const& builder,
|
||||
DetailsDialog& parent,
|
||||
Glib::RefPtr<Session> core,
|
||||
tr_torrent const* torrent);
|
||||
|
||||
TR_DISABLE_COPY_MOVE(EditTrackersDialog)
|
||||
|
||||
static std::unique_ptr<EditTrackersDialog> create(DetailsDialog& parent, Glib::RefPtr<Session> core, tr_torrent const* tor);
|
||||
|
||||
private:
|
||||
void on_response(int response);
|
||||
|
||||
private:
|
||||
DetailsDialog& parent_;
|
||||
Glib::RefPtr<Session> const core_;
|
||||
tr_torrent_id_t const torrent_id_;
|
||||
Gtk::TextView* const urls_view_;
|
||||
};
|
||||
|
||||
EditTrackersDialog::EditTrackersDialog(
|
||||
BaseObjectType* cast_item,
|
||||
Glib::RefPtr<Gtk::Builder> const& builder,
|
||||
DetailsDialog& parent,
|
||||
Glib::RefPtr<Session> core,
|
||||
tr_torrent const* torrent)
|
||||
: Gtk::Dialog(cast_item)
|
||||
, parent_(parent)
|
||||
, core_(core)
|
||||
, torrent_id_(tr_torrentId(torrent))
|
||||
, urls_view_(gtr_get_widget<Gtk::TextView>(builder, "urls_view"))
|
||||
{
|
||||
set_title(fmt::format(_("{torrent_name} - Edit Trackers"), fmt::arg("torrent_name", tr_torrentName(torrent))));
|
||||
set_transient_for(parent);
|
||||
|
||||
urls_view_->get_buffer()->set_text(tr_torrentGetTrackerList(torrent));
|
||||
|
||||
signal_response().connect([this](int response) { on_response(response); });
|
||||
}
|
||||
|
||||
std::unique_ptr<EditTrackersDialog> EditTrackersDialog::create(
|
||||
DetailsDialog& parent,
|
||||
Glib::RefPtr<Session> core,
|
||||
tr_torrent const* torrent)
|
||||
{
|
||||
auto const builder = Gtk::Builder::create_from_resource(gtr_get_full_resource_path("EditTrackersDialog.ui"));
|
||||
return std::unique_ptr<EditTrackersDialog>(
|
||||
gtr_get_widget_derived<EditTrackersDialog>(builder, "EditTrackersDialog", parent, core, torrent));
|
||||
}
|
||||
|
||||
void EditTrackersDialog::on_response(int response)
|
||||
{
|
||||
bool do_destroy = true;
|
||||
|
||||
if (response == Gtk::RESPONSE_ACCEPT)
|
||||
{
|
||||
auto const torrent_id = GPOINTER_TO_INT(dialog->get_data(TORRENT_ID_KEY));
|
||||
auto const* const text_buffer = static_cast<Gtk::TextBuffer*>(dialog->get_data(TEXT_BUFFER_KEY));
|
||||
auto const text_buffer = urls_view_->get_buffer();
|
||||
|
||||
if (auto* const tor = core_->find_torrent(torrent_id); tor != nullptr)
|
||||
if (auto* const tor = core_->find_torrent(torrent_id_); tor != nullptr)
|
||||
{
|
||||
if (tr_torrentSetTrackerList(tor, text_buffer->get_text(false).c_str()))
|
||||
{
|
||||
refresh();
|
||||
parent_.refresh();
|
||||
}
|
||||
else
|
||||
{
|
||||
Gtk::MessageDialog
|
||||
w(*dialog, _("List contains invalid URLs"), false, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_CLOSE, true);
|
||||
w(*this, _("List contains invalid URLs"), false, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_CLOSE, true);
|
||||
w.set_secondary_text(_("Please correct the errors and try again."));
|
||||
w.run();
|
||||
|
||||
|
@ -2296,63 +2199,18 @@ void DetailsDialog::Impl::on_edit_trackers_response(int response, std::shared_pt
|
|||
|
||||
if (do_destroy)
|
||||
{
|
||||
dialog.reset();
|
||||
hide();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void DetailsDialog::Impl::on_edit_trackers()
|
||||
{
|
||||
tr_torrent const* tor = tracker_list_get_current_torrent();
|
||||
|
||||
if (tor != nullptr)
|
||||
if (auto const* const tor = tracker_list_get_current_torrent(); tor != nullptr)
|
||||
{
|
||||
guint row;
|
||||
auto const torrent_id = tr_torrentId(tor);
|
||||
|
||||
auto d = std::make_shared<Gtk::Dialog>(
|
||||
fmt::format(_("{torrent_name} - Edit Trackers"), fmt::arg("torrent_name", tr_torrentName(tor))),
|
||||
dialog_,
|
||||
Gtk::DIALOG_MODAL | Gtk::DIALOG_DESTROY_WITH_PARENT);
|
||||
d->add_button(_("_Cancel"), Gtk::RESPONSE_CANCEL);
|
||||
d->add_button(_("_Save"), Gtk::RESPONSE_ACCEPT);
|
||||
d->signal_response().connect([this, d](int response) mutable { on_edit_trackers_response(response, d); });
|
||||
|
||||
row = 0;
|
||||
auto* t = Gtk::make_managed<HigWorkarea>();
|
||||
t->add_section_title(row, _("Tracker Announce URLs"));
|
||||
|
||||
auto* l = Gtk::make_managed<Gtk::Label>();
|
||||
l->set_markup(
|
||||
_("To add a backup URL, add it on the next line after a primary URL.\n"
|
||||
"To add a new primary URL, add it after a blank line."));
|
||||
l->set_justify(Gtk::JUSTIFY_LEFT);
|
||||
l->set_halign(Gtk::ALIGN_START);
|
||||
l->set_valign(Gtk::ALIGN_CENTER);
|
||||
t->add_wide_control(row, *l);
|
||||
|
||||
auto* w = Gtk::make_managed<Gtk::TextView>();
|
||||
w->get_buffer()->set_text(tr_torrentGetTrackerList(tor));
|
||||
auto* fr = Gtk::make_managed<Gtk::Frame>();
|
||||
fr->set_shadow_type(Gtk::SHADOW_IN);
|
||||
auto* sw = Gtk::make_managed<Gtk::ScrolledWindow>();
|
||||
sw->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
|
||||
sw->add(*w);
|
||||
fr->add(*sw);
|
||||
fr->set_size_request(500U, 166U);
|
||||
t->add_wide_tall_control(row, *fr);
|
||||
|
||||
l = Gtk::make_managed<Gtk::Label>();
|
||||
l->set_markup(_("Also see Default Public Trackers in Edit > Preferences > Network"));
|
||||
l->set_justify(Gtk::JUSTIFY_LEFT);
|
||||
l->set_halign(Gtk::ALIGN_START);
|
||||
l->set_valign(Gtk::ALIGN_CENTER);
|
||||
t->add_wide_control(row, *l);
|
||||
|
||||
gtr_dialog_set_content(*d, *t);
|
||||
|
||||
d->set_data(TORRENT_ID_KEY, GINT_TO_POINTER(torrent_id));
|
||||
d->set_data(TEXT_BUFFER_KEY, gtr_get_ptr(w->get_buffer()));
|
||||
|
||||
auto d = std::shared_ptr<EditTrackersDialog>(EditTrackersDialog::create(dialog_, core_, tor));
|
||||
d->signal_hide().connect([d]() mutable { d.reset(); });
|
||||
d->show();
|
||||
}
|
||||
}
|
||||
|
@ -2367,15 +2225,70 @@ void DetailsDialog::Impl::on_tracker_list_selection_changed()
|
|||
edit_trackers_button_->set_sensitive(tor != nullptr);
|
||||
}
|
||||
|
||||
void DetailsDialog::Impl::on_add_tracker_response(int response, std::shared_ptr<Gtk::Dialog>& dialog)
|
||||
namespace
|
||||
{
|
||||
|
||||
class AddTrackerDialog : public Gtk::Dialog
|
||||
{
|
||||
public:
|
||||
AddTrackerDialog(
|
||||
BaseObjectType* cast_item,
|
||||
Glib::RefPtr<Gtk::Builder> const& builder,
|
||||
DetailsDialog& parent,
|
||||
Glib::RefPtr<Session> core,
|
||||
tr_torrent const* torrent);
|
||||
|
||||
TR_DISABLE_COPY_MOVE(AddTrackerDialog)
|
||||
|
||||
static std::unique_ptr<AddTrackerDialog> create(DetailsDialog& parent, Glib::RefPtr<Session> core, tr_torrent const* tor);
|
||||
|
||||
private:
|
||||
void on_response(int response);
|
||||
|
||||
private:
|
||||
DetailsDialog& parent_;
|
||||
Glib::RefPtr<Session> const core_;
|
||||
tr_torrent_id_t const torrent_id_;
|
||||
Gtk::Entry* const url_entry_;
|
||||
};
|
||||
|
||||
AddTrackerDialog::AddTrackerDialog(
|
||||
BaseObjectType* cast_item,
|
||||
Glib::RefPtr<Gtk::Builder> const& builder,
|
||||
DetailsDialog& parent,
|
||||
Glib::RefPtr<Session> core,
|
||||
tr_torrent const* torrent)
|
||||
: Gtk::Dialog(cast_item)
|
||||
, parent_(parent)
|
||||
, core_(core)
|
||||
, torrent_id_(tr_torrentId(torrent))
|
||||
, url_entry_(gtr_get_widget<Gtk::Entry>(builder, "url_entry"))
|
||||
{
|
||||
set_title(fmt::format(_("{torrent_name} - Add Tracker"), fmt::arg("torrent_name", tr_torrentName(torrent))));
|
||||
set_transient_for(parent);
|
||||
|
||||
gtr_paste_clipboard_url_into_entry(*url_entry_);
|
||||
|
||||
signal_response().connect([this](int response) { on_response(response); });
|
||||
}
|
||||
|
||||
std::unique_ptr<AddTrackerDialog> AddTrackerDialog::create(
|
||||
DetailsDialog& parent,
|
||||
Glib::RefPtr<Session> core,
|
||||
tr_torrent const* torrent)
|
||||
{
|
||||
auto const builder = Gtk::Builder::create_from_resource(gtr_get_full_resource_path("AddTrackerDialog.ui"));
|
||||
return std::unique_ptr<AddTrackerDialog>(
|
||||
gtr_get_widget_derived<AddTrackerDialog>(builder, "AddTrackerDialog", parent, core, torrent));
|
||||
}
|
||||
|
||||
void AddTrackerDialog::on_response(int response)
|
||||
{
|
||||
bool destroy = true;
|
||||
|
||||
if (response == Gtk::RESPONSE_ACCEPT)
|
||||
{
|
||||
auto const* const e = static_cast<Gtk::Entry*>(dialog->get_data(URL_ENTRY_KEY));
|
||||
auto const torrent_id = GPOINTER_TO_INT(dialog->get_data(TORRENT_ID_KEY));
|
||||
auto const url = gtr_str_strip(e->get_text());
|
||||
auto const url = gtr_str_strip(url_entry_->get_text());
|
||||
|
||||
if (!url.empty())
|
||||
{
|
||||
|
@ -2388,18 +2301,18 @@ void DetailsDialog::Impl::on_add_tracker_response(int response, std::shared_ptr<
|
|||
tr_variantInitDict(&top, 2);
|
||||
tr_variantDictAddStrView(&top, TR_KEY_method, "torrent-set"sv);
|
||||
args = tr_variantDictAddDict(&top, TR_KEY_arguments, 2);
|
||||
tr_variantDictAddInt(args, TR_KEY_id, torrent_id);
|
||||
tr_variantDictAddInt(args, TR_KEY_id, torrent_id_);
|
||||
trackers = tr_variantDictAddList(args, TR_KEY_trackerAdd, 1);
|
||||
tr_variantListAddStr(trackers, url.raw());
|
||||
|
||||
core_->exec(&top);
|
||||
refresh();
|
||||
parent_.refresh();
|
||||
|
||||
tr_variantClear(&top);
|
||||
}
|
||||
else
|
||||
{
|
||||
gtr_unrecognized_url_dialog(*dialog, url);
|
||||
gtr_unrecognized_url_dialog(*this, url);
|
||||
destroy = false;
|
||||
}
|
||||
}
|
||||
|
@ -2407,38 +2320,19 @@ void DetailsDialog::Impl::on_add_tracker_response(int response, std::shared_ptr<
|
|||
|
||||
if (destroy)
|
||||
{
|
||||
dialog.reset();
|
||||
hide();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void DetailsDialog::Impl::on_tracker_list_add_button_clicked()
|
||||
{
|
||||
tr_torrent const* tor = tracker_list_get_current_torrent();
|
||||
|
||||
if (tor != nullptr)
|
||||
if (auto const* const tor = tracker_list_get_current_torrent(); tor != nullptr)
|
||||
{
|
||||
guint row;
|
||||
|
||||
auto w = std::make_shared<Gtk::Dialog>(
|
||||
fmt::format(_("{torrent_name} - Add Tracker"), fmt::arg("torrent_name", tr_torrentName(tor))),
|
||||
dialog_,
|
||||
Gtk::DIALOG_DESTROY_WITH_PARENT);
|
||||
w->add_button(_("_Cancel"), Gtk::RESPONSE_CANCEL);
|
||||
w->add_button(_("_Add"), Gtk::RESPONSE_ACCEPT);
|
||||
w->signal_response().connect([this, w](int response) mutable { on_add_tracker_response(response, w); });
|
||||
|
||||
row = 0;
|
||||
auto* t = Gtk::make_managed<HigWorkarea>();
|
||||
t->add_section_title(row, _("Tracker"));
|
||||
auto* e = Gtk::make_managed<Gtk::Entry>();
|
||||
e->set_size_request(400, -1);
|
||||
gtr_paste_clipboard_url_into_entry(*e);
|
||||
w->set_data(URL_ENTRY_KEY, e);
|
||||
w->set_data(TORRENT_ID_KEY, GINT_TO_POINTER(tr_torrentId(tor)));
|
||||
t->add_row(row, _("_Announce URL:"), *e);
|
||||
gtr_dialog_set_content(*w, *t);
|
||||
|
||||
w->show_all();
|
||||
auto d = std::shared_ptr<AddTrackerDialog>(AddTrackerDialog::create(dialog_, core_, tor));
|
||||
d->signal_hide().connect([d]() mutable { d.reset(); });
|
||||
d->show();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2469,22 +2363,16 @@ void DetailsDialog::Impl::on_tracker_list_remove_button_clicked()
|
|||
}
|
||||
}
|
||||
|
||||
Gtk::Widget* DetailsDialog::Impl::tracker_page_new()
|
||||
void DetailsDialog::Impl::tracker_page_init(Glib::RefPtr<Gtk::Builder> const& /*builder*/)
|
||||
{
|
||||
int const pad = (GUI_PAD + GUI_PAD_BIG) / 2;
|
||||
|
||||
auto* vbox = Gtk::make_managed<Gtk::Box>(Gtk::ORIENTATION_VERTICAL, GUI_PAD);
|
||||
vbox->set_border_width(GUI_PAD_BIG);
|
||||
|
||||
tracker_store_ = Gtk::ListStore::create(tracker_cols);
|
||||
|
||||
trackers_filtered_ = Gtk::TreeModelFilter::create(tracker_store_);
|
||||
trackers_filtered_->set_visible_func(sigc::mem_fun(*this, &Impl::trackerVisibleFunc));
|
||||
|
||||
auto* hbox = Gtk::make_managed<Gtk::Box>(Gtk::ORIENTATION_HORIZONTAL, GUI_PAD_BIG);
|
||||
|
||||
tracker_view_ = Gtk::make_managed<Gtk::TreeView>(trackers_filtered_);
|
||||
tracker_view_->set_headers_visible(false);
|
||||
tracker_view_->set_model(trackers_filtered_);
|
||||
tracker_view_->signal_button_press_event().connect([this](GdkEventButton* event)
|
||||
{ return on_tree_view_button_pressed(tracker_view_, event); });
|
||||
tracker_view_->signal_button_release_event().connect([this](GdkEventButton* event)
|
||||
|
@ -2516,44 +2404,15 @@ Gtk::Widget* DetailsDialog::Impl::tracker_page_new()
|
|||
c->add_attribute(r->property_markup(), tracker_cols.text);
|
||||
}
|
||||
|
||||
auto* sw = Gtk::make_managed<Gtk::ScrolledWindow>();
|
||||
sw->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
|
||||
sw->add(*tracker_view_);
|
||||
auto* w = Gtk::make_managed<Gtk::Frame>();
|
||||
w->set_shadow_type(Gtk::SHADOW_IN);
|
||||
w->add(*sw);
|
||||
|
||||
hbox->pack_start(*w, true, true);
|
||||
|
||||
auto* v = Gtk::make_managed<Gtk::Box>(Gtk::ORIENTATION_VERTICAL, GUI_PAD);
|
||||
|
||||
add_tracker_button_ = Gtk::make_managed<Gtk::Button>(_("_Add"), true);
|
||||
add_tracker_button_->signal_clicked().connect(sigc::mem_fun(*this, &Impl::on_tracker_list_add_button_clicked));
|
||||
v->pack_start(*add_tracker_button_, false, false);
|
||||
|
||||
edit_trackers_button_ = Gtk::make_managed<Gtk::Button>(_("_Edit"), true);
|
||||
edit_trackers_button_->signal_clicked().connect(sigc::mem_fun(*this, &Impl::on_edit_trackers));
|
||||
v->pack_start(*edit_trackers_button_, false, false);
|
||||
|
||||
remove_tracker_button_ = Gtk::make_managed<Gtk::Button>(_("_Remove"), true);
|
||||
remove_tracker_button_->signal_clicked().connect(sigc::mem_fun(*this, &Impl::on_tracker_list_remove_button_clicked));
|
||||
v->pack_start(*remove_tracker_button_, false, false);
|
||||
|
||||
hbox->pack_start(*v, false, false);
|
||||
|
||||
vbox->pack_start(*hbox, true, true);
|
||||
|
||||
scrape_check_ = Gtk::make_managed<Gtk::CheckButton>(_("Show _more details"), true);
|
||||
scrape_check_->set_active(gtr_pref_flag_get(TR_KEY_show_tracker_scrapes));
|
||||
scrape_check_->signal_toggled().connect(sigc::mem_fun(*this, &Impl::onScrapeToggled));
|
||||
vbox->pack_start(*scrape_check_, false, false);
|
||||
|
||||
all_check_ = Gtk::make_managed<Gtk::CheckButton>(_("Show _backup trackers"), true);
|
||||
all_check_->set_active(gtr_pref_flag_get(TR_KEY_show_backup_trackers));
|
||||
all_check_->signal_toggled().connect(sigc::mem_fun(*this, &Impl::onBackupToggled));
|
||||
vbox->pack_start(*all_check_, false, false);
|
||||
|
||||
return vbox;
|
||||
}
|
||||
|
||||
/****
|
||||
|
@ -2592,54 +2451,79 @@ DetailsDialog::Impl::~Impl()
|
|||
|
||||
std::unique_ptr<DetailsDialog> DetailsDialog::create(Gtk::Window& parent, Glib::RefPtr<Session> const& core)
|
||||
{
|
||||
return std::unique_ptr<DetailsDialog>(new DetailsDialog(parent, core));
|
||||
auto const builder = Gtk::Builder::create_from_resource(gtr_get_full_resource_path("DetailsDialog.ui"));
|
||||
return std::unique_ptr<DetailsDialog>(gtr_get_widget_derived<DetailsDialog>(builder, "DetailsDialog", parent, core));
|
||||
}
|
||||
|
||||
DetailsDialog::DetailsDialog(Gtk::Window& parent, Glib::RefPtr<Session> const& core)
|
||||
: Gtk::Dialog({}, parent)
|
||||
, impl_(std::make_unique<Impl>(*this, core))
|
||||
DetailsDialog::DetailsDialog(
|
||||
BaseObjectType* cast_item,
|
||||
Glib::RefPtr<Gtk::Builder> const& builder,
|
||||
Gtk::Window& parent,
|
||||
Glib::RefPtr<Session> const& core)
|
||||
: Gtk::Dialog(cast_item)
|
||||
, impl_(std::make_unique<Impl>(*this, builder, core))
|
||||
{
|
||||
set_transient_for(parent);
|
||||
}
|
||||
|
||||
DetailsDialog::~DetailsDialog() = default;
|
||||
|
||||
DetailsDialog::Impl::Impl(DetailsDialog& dialog, Glib::RefPtr<Session> const& core)
|
||||
DetailsDialog::Impl::Impl(DetailsDialog& dialog, Glib::RefPtr<Gtk::Builder> const& builder, Glib::RefPtr<Session> const& core)
|
||||
: dialog_(dialog)
|
||||
, core_(core)
|
||||
, honor_limits_check_(gtr_get_widget<Gtk::CheckButton>(builder, "honor_limits_check"))
|
||||
, up_limited_check_(gtr_get_widget<Gtk::CheckButton>(builder, "upload_limit_check"))
|
||||
, up_limit_sping_(gtr_get_widget<Gtk::SpinButton>(builder, "upload_limit_spin"))
|
||||
, down_limited_check_(gtr_get_widget<Gtk::CheckButton>(builder, "download_limit_check"))
|
||||
, down_limit_spin_(gtr_get_widget<Gtk::SpinButton>(builder, "download_limit_spin"))
|
||||
, bandwidth_combo_(gtr_get_widget<Gtk::ComboBox>(builder, "priority_combo"))
|
||||
, ratio_combo_(gtr_get_widget<Gtk::ComboBox>(builder, "ratio_limit_combo"))
|
||||
, ratio_spin_(gtr_get_widget<Gtk::SpinButton>(builder, "ratio_limit_spin"))
|
||||
, idle_combo_(gtr_get_widget<Gtk::ComboBox>(builder, "idle_limit_combo"))
|
||||
, idle_spin_(gtr_get_widget<Gtk::SpinButton>(builder, "idle_limit_spin"))
|
||||
, max_peers_spin_(gtr_get_widget<Gtk::SpinButton>(builder, "max_peers_spin"))
|
||||
, added_lb_(gtr_get_widget<Gtk::Label>(builder, "added_value_label"))
|
||||
, size_lb_(gtr_get_widget<Gtk::Label>(builder, "torrent_size_value_label"))
|
||||
, state_lb_(gtr_get_widget<Gtk::Label>(builder, "state_value_label"))
|
||||
, have_lb_(gtr_get_widget<Gtk::Label>(builder, "have_value_label"))
|
||||
, dl_lb_(gtr_get_widget<Gtk::Label>(builder, "downloaded_value_label"))
|
||||
, ul_lb_(gtr_get_widget<Gtk::Label>(builder, "uploaded_value_label"))
|
||||
, error_lb_(gtr_get_widget<Gtk::Label>(builder, "error_value_label"))
|
||||
, date_started_lb_(gtr_get_widget<Gtk::Label>(builder, "running_time_value_label"))
|
||||
, eta_lb_(gtr_get_widget<Gtk::Label>(builder, "remaining_time_value_label"))
|
||||
, last_activity_lb_(gtr_get_widget<Gtk::Label>(builder, "last_activity_value_label"))
|
||||
, hash_lb_(gtr_get_widget<Gtk::Label>(builder, "hash_value_label"))
|
||||
, privacy_lb_(gtr_get_widget<Gtk::Label>(builder, "privacy_value_label"))
|
||||
, origin_lb_(gtr_get_widget<Gtk::Label>(builder, "origin_value_label"))
|
||||
, destination_lb_(gtr_get_widget<Gtk::Label>(builder, "location_value_label"))
|
||||
, webseed_view_(gtr_get_widget<Gtk::ScrolledWindow>(builder, "webseeds_view_scroll"))
|
||||
, peer_view_(gtr_get_widget<Gtk::TreeView>(builder, "peers_view"))
|
||||
, more_peer_details_check_(gtr_get_widget<Gtk::CheckButton>(builder, "more_peer_details_check"))
|
||||
, add_tracker_button_(gtr_get_widget<Gtk::Button>(builder, "add_tracker_button"))
|
||||
, edit_trackers_button_(gtr_get_widget<Gtk::Button>(builder, "edit_tracker_button"))
|
||||
, remove_tracker_button_(gtr_get_widget<Gtk::Button>(builder, "remove_tracker_button"))
|
||||
, tracker_view_(gtr_get_widget<Gtk::TreeView>(builder, "trackers_view"))
|
||||
, scrape_check_(gtr_get_widget<Gtk::CheckButton>(builder, "more_tracker_details_check"))
|
||||
, all_check_(gtr_get_widget<Gtk::CheckButton>(builder, "backup_trackers_check"))
|
||||
, file_list_(gtr_get_widget_derived<FileList>(builder, "files_view_scroll", "files_view", core, 0))
|
||||
, file_label_(gtr_get_widget<Gtk::Label>(builder, "files_label"))
|
||||
{
|
||||
/* create the dialog */
|
||||
dialog_.add_button(_("_Close"), Gtk::RESPONSE_CLOSE);
|
||||
dialog_.set_role("tr-info");
|
||||
|
||||
/* return saved window size */
|
||||
dialog_.resize((int)gtr_pref_int_get(TR_KEY_details_window_width), (int)gtr_pref_int_get(TR_KEY_details_window_height));
|
||||
dialog_.signal_size_allocate().connect(sigc::mem_fun(*this, &Impl::on_details_window_size_allocated));
|
||||
|
||||
dialog_.signal_response().connect(sigc::hide<0>(sigc::mem_fun(dialog_, &DetailsDialog::hide)));
|
||||
dialog_.set_border_width(GUI_PAD);
|
||||
|
||||
auto* n = Gtk::make_managed<Gtk::Notebook>();
|
||||
n->set_border_width(GUI_PAD);
|
||||
info_page_init(builder);
|
||||
peer_page_init(builder);
|
||||
tracker_page_init(builder);
|
||||
options_page_init(builder);
|
||||
|
||||
n->append_page(*info_page_new(), _("Information"));
|
||||
n->append_page(*peer_page_new(), _("Peers"));
|
||||
n->append_page(*tracker_page_new(), _("Trackers"));
|
||||
|
||||
auto* v = Gtk::make_managed<Gtk::Box>(Gtk::ORIENTATION_VERTICAL);
|
||||
file_list_ = Gtk::make_managed<FileList>(core, 0);
|
||||
file_label_ = Gtk::make_managed<Gtk::Label>(_("File listing not available for combined torrent properties"));
|
||||
v->pack_start(*file_list_, true, true, 0);
|
||||
v->pack_start(*file_label_, true, true, 0);
|
||||
v->set_border_width(GUI_PAD_BIG);
|
||||
n->append_page(*v, _("Files"));
|
||||
|
||||
n->append_page(*options_page_new(), _("Options"));
|
||||
|
||||
gtr_dialog_set_content(dialog_, *n);
|
||||
periodic_refresh_tag_ = Glib::signal_timeout().connect_seconds(
|
||||
[this]() { return refresh(), true; },
|
||||
SECONDARY_WINDOW_REFRESH_INTERVAL_SECONDS);
|
||||
|
||||
auto* const n = gtr_get_widget<Gtk::Notebook>(builder, "dialog_pages");
|
||||
n->set_current_page(last_page_);
|
||||
last_page_tag_ = n->signal_switch_page().connect([](Widget*, guint page) { DetailsDialog::Impl::last_page_ = page; });
|
||||
}
|
||||
|
@ -2649,6 +2533,11 @@ void DetailsDialog::set_torrents(std::vector<tr_torrent_id_t> const& ids)
|
|||
impl_->set_torrents(ids);
|
||||
}
|
||||
|
||||
void DetailsDialog::refresh()
|
||||
{
|
||||
impl_->refresh();
|
||||
}
|
||||
|
||||
void DetailsDialog::Impl::set_torrents(std::vector<tr_torrent_id_t> const& ids)
|
||||
{
|
||||
Glib::ustring title;
|
||||
|
|
|
@ -18,6 +18,11 @@ class Session;
|
|||
class DetailsDialog : public Gtk::Dialog
|
||||
{
|
||||
public:
|
||||
DetailsDialog(
|
||||
BaseObjectType* cast_item,
|
||||
Glib::RefPtr<Gtk::Builder> const& builder,
|
||||
Gtk::Window& parent,
|
||||
Glib::RefPtr<Session> const& core);
|
||||
~DetailsDialog() override;
|
||||
|
||||
TR_DISABLE_COPY_MOVE(DetailsDialog)
|
||||
|
@ -25,9 +30,7 @@ public:
|
|||
static std::unique_ptr<DetailsDialog> create(Gtk::Window& parent, Glib::RefPtr<Session> const& core);
|
||||
|
||||
void set_torrents(std::vector<tr_torrent_id_t> const& torrent_ids);
|
||||
|
||||
protected:
|
||||
DetailsDialog(Gtk::Window& parent, Glib::RefPtr<Session> const& core);
|
||||
void refresh();
|
||||
|
||||
private:
|
||||
class Impl;
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,153 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Generated with glade 3.38.2 -->
|
||||
<interface domain="transmission-gtk">
|
||||
<requires lib="gtk+" version="3.24"/>
|
||||
<object class="GtkDialog" id="EditTrackersDialog">
|
||||
<property name="can-focus">False</property>
|
||||
<property name="border-width">6</property>
|
||||
<property name="modal">True</property>
|
||||
<property name="type-hint">dialog</property>
|
||||
<child internal-child="vbox">
|
||||
<object class="GtkBox" id="dialog_layout">
|
||||
<property name="can-focus">False</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">6</property>
|
||||
<child internal-child="action_area">
|
||||
<object class="GtkButtonBox" id="dialog_buttons">
|
||||
<property name="can-focus">False</property>
|
||||
<property name="layout-style">end</property>
|
||||
<child>
|
||||
<object class="GtkButton" id="cancel_button">
|
||||
<property name="label" translatable="yes">_Cancel</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="receives-default">True</property>
|
||||
<property name="use-underline">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="save_button">
|
||||
<property name="label" translatable="yes">_Save</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="receives-default">True</property>
|
||||
<property name="use-underline">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox" id="dialog_content_layout">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">6</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="urls_section_title">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="label" translatable="yes">Tracker Announce URLs</property>
|
||||
<property name="xalign">0</property>
|
||||
<attributes>
|
||||
<attribute name="weight" value="bold"/>
|
||||
</attributes>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<!-- n-columns=2 n-rows=3 -->
|
||||
<object class="GtkGrid" id="urls_section_layout">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="margin-start">18</property>
|
||||
<property name="row-spacing">6</property>
|
||||
<property name="column-spacing">12</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="urls_section_top_comment_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="label" translatable="yes">To add a backup URL, add it on the next line after a primary URL.
|
||||
To add a new primary URL, add it after a blank line.</property>
|
||||
<property name="xalign">0</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">0</property>
|
||||
<property name="width">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow" id="urls_view_scroll">
|
||||
<property name="width-request">500</property>
|
||||
<property name="height-request">166</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="shadow-type">in</property>
|
||||
<child>
|
||||
<object class="GtkTextView" id="urls_view">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="accepts-tab">False</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">1</property>
|
||||
<property name="width">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="urls_section_bottom_comment_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="label" translatable="yes">Also see Default Public Trackers in Edit > Preferences > Network</property>
|
||||
<property name="xalign">0</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">2</property>
|
||||
<property name="width">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<action-widgets>
|
||||
<action-widget response="-6">cancel_button</action-widget>
|
||||
<action-widget response="-3">save_button</action-widget>
|
||||
</action-widgets>
|
||||
</object>
|
||||
</interface>
|
|
@ -4,7 +4,7 @@
|
|||
// License text can be found in the licenses/ folder.
|
||||
|
||||
#include <algorithm>
|
||||
#include <climits> /* INT_MAX */
|
||||
#include <climits> // INT_MAX
|
||||
#include <cstddef>
|
||||
#include <list>
|
||||
#include <memory>
|
||||
|
@ -22,7 +22,7 @@
|
|||
#include <libtransmission/utils.h>
|
||||
|
||||
#include "FileList.h"
|
||||
#include "HigWorkarea.h"
|
||||
#include "HigWorkarea.h" // GUI_PAD, GUI_PAD_BIG
|
||||
#include "IconCache.h"
|
||||
#include "PrefsDialog.h"
|
||||
#include "Session.h"
|
||||
|
@ -81,7 +81,14 @@ FileModelColumns const file_cols;
|
|||
class FileList::Impl
|
||||
{
|
||||
public:
|
||||
Impl(FileList& widget, Glib::RefPtr<Session> const& core, tr_torrent_id_t tor_id);
|
||||
Impl(FileList& widget, Gtk::TreeView* view, Glib::RefPtr<Session> const& core, tr_torrent_id_t torrent_id);
|
||||
Impl(FileList& widget, Glib::RefPtr<Session> const& core, tr_torrent_id_t torrent_id);
|
||||
Impl(
|
||||
FileList& widget,
|
||||
Glib::RefPtr<Gtk::Builder> const& builder,
|
||||
Glib::ustring const& view_name,
|
||||
Glib::RefPtr<Session> const& core,
|
||||
tr_torrent_id_t torrent_id);
|
||||
~Impl();
|
||||
|
||||
TR_DISABLE_COPY_MOVE(Impl)
|
||||
|
@ -838,13 +845,23 @@ FileList::FileList(Glib::RefPtr<Session> const& core, tr_torrent_id_t tor_id)
|
|||
{
|
||||
}
|
||||
|
||||
FileList::Impl::Impl(FileList& widget, Glib::RefPtr<Session> const& core, tr_torrent_id_t tor_id)
|
||||
FileList::FileList(
|
||||
BaseObjectType* cast_item,
|
||||
Glib::RefPtr<Gtk::Builder> const& builder,
|
||||
Glib::ustring const& view_name,
|
||||
Glib::RefPtr<Session> const& core,
|
||||
tr_torrent_id_t torrent_id)
|
||||
: Gtk::ScrolledWindow(cast_item)
|
||||
, impl_(std::make_unique<Impl>(*this, builder, view_name, core, torrent_id))
|
||||
{
|
||||
}
|
||||
|
||||
FileList::Impl::Impl(FileList& widget, Gtk::TreeView* view, Glib::RefPtr<Session> const& core, tr_torrent_id_t torrent_id)
|
||||
: widget_(widget)
|
||||
, core_(core)
|
||||
, view_(view)
|
||||
{
|
||||
/* create the view */
|
||||
view_ = Gtk::make_managed<Gtk::TreeView>();
|
||||
view_->set_border_width(GUI_PAD_BIG);
|
||||
view_->signal_button_press_event().connect(sigc::mem_fun(*this, &Impl::onViewButtonPressed), false);
|
||||
view_->signal_row_activated().connect(sigc::mem_fun(*this, &Impl::onRowActivated));
|
||||
view_->signal_button_release_event().connect([this](GdkEventButton* event)
|
||||
|
@ -951,13 +968,29 @@ FileList::Impl::Impl(FileList& widget, Glib::RefPtr<Session> const& core, tr_tor
|
|||
/* add tooltip to tree */
|
||||
view_->set_tooltip_column(file_cols.label_esc.index());
|
||||
|
||||
set_torrent(torrent_id);
|
||||
}
|
||||
|
||||
FileList::Impl::Impl(FileList& widget, Glib::RefPtr<Session> const& core, tr_torrent_id_t torrent_id)
|
||||
: Impl(widget, Gtk::make_managed<Gtk::TreeView>(), core, torrent_id)
|
||||
{
|
||||
view_->set_border_width(GUI_PAD_BIG);
|
||||
|
||||
/* create the scrolled window and stick the view in it */
|
||||
widget_.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
|
||||
widget_.set_shadow_type(Gtk::SHADOW_IN);
|
||||
widget_.add(*view_);
|
||||
widget_.set_size_request(-1, 200);
|
||||
}
|
||||
|
||||
set_torrent(tor_id);
|
||||
FileList::Impl::Impl(
|
||||
FileList& widget,
|
||||
Glib::RefPtr<Gtk::Builder> const& builder,
|
||||
Glib::ustring const& view_name,
|
||||
Glib::RefPtr<Session> const& core,
|
||||
tr_torrent_id_t torrent_id)
|
||||
: Impl(widget, gtr_get_widget<Gtk::TreeView>(builder, view_name), core, torrent_id)
|
||||
{
|
||||
}
|
||||
|
||||
FileList::~FileList() = default;
|
||||
|
|
|
@ -17,6 +17,12 @@ class FileList : public Gtk::ScrolledWindow
|
|||
{
|
||||
public:
|
||||
FileList(Glib::RefPtr<Session> const& core, tr_torrent_id_t torrent_id);
|
||||
FileList(
|
||||
BaseObjectType* cast_item,
|
||||
Glib::RefPtr<Gtk::Builder> const& builder,
|
||||
Glib::ustring const& view_name,
|
||||
Glib::RefPtr<Session> const& core,
|
||||
tr_torrent_id_t torrent_id);
|
||||
~FileList() override;
|
||||
|
||||
TR_DISABLE_COPY_MOVE(FileList)
|
||||
|
|
145
gtk/FilterBar.cc
145
gtk/FilterBar.cc
|
@ -12,10 +12,10 @@
|
|||
#include <glibmm.h>
|
||||
#include <glibmm/i18n.h>
|
||||
|
||||
#include "FaviconCache.h" /* gtr_get_favicon() */
|
||||
#include "FaviconCache.h" // gtr_get_favicon()
|
||||
#include "FilterBar.h"
|
||||
#include "HigWorkarea.h" /* GUI_PAD */
|
||||
#include "Session.h" /* MC_TORRENT */
|
||||
#include "HigWorkarea.h" // GUI_PAD
|
||||
#include "Session.h" // torrent_cols
|
||||
#include "Utils.h"
|
||||
|
||||
namespace
|
||||
|
@ -38,8 +38,11 @@ public:
|
|||
Glib::RefPtr<Gtk::TreeModel> get_filter_model() const;
|
||||
|
||||
private:
|
||||
Gtk::ComboBox* activity_combo_box_new(Glib::RefPtr<Gtk::TreeModel> const& tmodel);
|
||||
Gtk::ComboBox* tracker_combo_box_new(Glib::RefPtr<Gtk::TreeModel> const& tmodel);
|
||||
template<typename T>
|
||||
T* get_template_child(char const* name) const;
|
||||
|
||||
void activity_combo_box_init(Gtk::ComboBox* combo, Glib::RefPtr<Gtk::TreeModel> const& tmodel);
|
||||
void tracker_combo_box_init(Gtk::ComboBox* combo, Glib::RefPtr<Gtk::TreeModel> const& tmodel);
|
||||
|
||||
void update_count_label_idle();
|
||||
|
||||
|
@ -332,31 +335,32 @@ Gtk::CellRendererText* number_renderer_new()
|
|||
|
||||
} // namespace
|
||||
|
||||
Gtk::ComboBox* FilterBar::Impl::tracker_combo_box_new(Glib::RefPtr<Gtk::TreeModel> const& tmodel)
|
||||
void FilterBar::Impl::tracker_combo_box_init(Gtk::ComboBox* combo, Glib::RefPtr<Gtk::TreeModel> const& tmodel)
|
||||
{
|
||||
/* create the tracker combobox */
|
||||
auto const cat_model = tracker_filter_model_new(tmodel);
|
||||
auto* c = Gtk::make_managed<Gtk::ComboBox>(static_cast<Glib::RefPtr<Gtk::TreeModel> const&>(cat_model));
|
||||
c->set_row_separator_func(&is_it_a_separator);
|
||||
c->set_active(0);
|
||||
|
||||
combo->set_model(cat_model);
|
||||
combo->set_row_separator_func(&is_it_a_separator);
|
||||
combo->set_active(0);
|
||||
|
||||
{
|
||||
auto* r = Gtk::make_managed<Gtk::CellRendererPixbuf>();
|
||||
c->pack_start(*r, false);
|
||||
c->set_cell_data_func(*r, [r](auto const& iter) { render_pixbuf_func(r, iter); });
|
||||
c->add_attribute(r->property_pixbuf(), tracker_filter_cols.pixbuf);
|
||||
combo->pack_start(*r, false);
|
||||
combo->set_cell_data_func(*r, [r](auto const& iter) { render_pixbuf_func(r, iter); });
|
||||
combo->add_attribute(r->property_pixbuf(), tracker_filter_cols.pixbuf);
|
||||
}
|
||||
|
||||
{
|
||||
auto* r = Gtk::make_managed<Gtk::CellRendererText>();
|
||||
c->pack_start(*r, false);
|
||||
c->add_attribute(r->property_text(), tracker_filter_cols.displayname);
|
||||
combo->pack_start(*r, false);
|
||||
combo->add_attribute(r->property_text(), tracker_filter_cols.displayname);
|
||||
}
|
||||
|
||||
{
|
||||
auto* r = number_renderer_new();
|
||||
c->pack_end(*r, true);
|
||||
c->set_cell_data_func(*r, [r](auto const& iter) { render_number_func(r, iter); });
|
||||
combo->pack_end(*r, true);
|
||||
combo->set_cell_data_func(*r, [r](auto const& iter) { render_number_func(r, iter); });
|
||||
}
|
||||
|
||||
torrent_model_row_changed_tag_ = tmodel->signal_row_changed().connect(
|
||||
|
@ -365,8 +369,6 @@ Gtk::ComboBox* FilterBar::Impl::tracker_combo_box_new(Glib::RefPtr<Gtk::TreeMode
|
|||
[cat_model](auto const& /*path*/, auto const& /*iter*/) { tracker_model_update_idle(cat_model); });
|
||||
torrent_model_row_deleted_cb_tag_ = tmodel->signal_row_deleted().connect( //
|
||||
[cat_model](auto const& /*path*/) { tracker_model_update_idle(cat_model); });
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
namespace
|
||||
|
@ -557,30 +559,31 @@ void activity_model_update_idle(Glib::RefPtr<Gtk::ListStore> const& activity_mod
|
|||
|
||||
} // namespace
|
||||
|
||||
Gtk::ComboBox* FilterBar::Impl::activity_combo_box_new(Glib::RefPtr<Gtk::TreeModel> const& tmodel)
|
||||
void FilterBar::Impl::activity_combo_box_init(Gtk::ComboBox* combo, Glib::RefPtr<Gtk::TreeModel> const& tmodel)
|
||||
{
|
||||
auto const activity_model = activity_filter_model_new(tmodel);
|
||||
auto* c = Gtk::make_managed<Gtk::ComboBox>(static_cast<Glib::RefPtr<Gtk::TreeModel> const&>(activity_model));
|
||||
c->set_row_separator_func(&activity_is_it_a_separator);
|
||||
c->set_active(0);
|
||||
|
||||
combo->set_model(activity_model);
|
||||
combo->set_row_separator_func(&activity_is_it_a_separator);
|
||||
combo->set_active(0);
|
||||
|
||||
{
|
||||
auto* r = Gtk::make_managed<Gtk::CellRendererPixbuf>();
|
||||
c->pack_start(*r, false);
|
||||
c->add_attribute(r->property_icon_name(), activity_filter_cols.icon_name);
|
||||
c->set_cell_data_func(*r, [r](auto const& iter) { render_activity_pixbuf_func(r, iter); });
|
||||
combo->pack_start(*r, false);
|
||||
combo->add_attribute(r->property_icon_name(), activity_filter_cols.icon_name);
|
||||
combo->set_cell_data_func(*r, [r](auto const& iter) { render_activity_pixbuf_func(r, iter); });
|
||||
}
|
||||
|
||||
{
|
||||
auto* r = Gtk::make_managed<Gtk::CellRendererText>();
|
||||
c->pack_start(*r, true);
|
||||
c->add_attribute(r->property_text(), activity_filter_cols.name);
|
||||
combo->pack_start(*r, true);
|
||||
combo->add_attribute(r->property_text(), activity_filter_cols.name);
|
||||
}
|
||||
|
||||
{
|
||||
auto* r = number_renderer_new();
|
||||
c->pack_end(*r, true);
|
||||
c->set_cell_data_func(*r, [r](auto const& iter) { render_number_func(r, iter); });
|
||||
combo->pack_end(*r, true);
|
||||
combo->set_cell_data_func(*r, [r](auto const& iter) { render_number_func(r, iter); });
|
||||
}
|
||||
|
||||
activity_model_row_changed_tag_ = tmodel->signal_row_changed().connect(
|
||||
|
@ -589,8 +592,6 @@ Gtk::ComboBox* FilterBar::Impl::activity_combo_box_new(Glib::RefPtr<Gtk::TreeMod
|
|||
[activity_model](auto const& /*path*/, auto const& /*iter*/) { activity_model_update_idle(activity_model); });
|
||||
activity_model_row_deleted_cb_tag_ = tmodel->signal_row_deleted().connect( //
|
||||
[activity_model](auto const& /*path*/) { activity_model_update_idle(activity_model); });
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
/****
|
||||
|
@ -731,24 +732,65 @@ void FilterBar::Impl::update_count_label_idle()
|
|||
****
|
||||
***/
|
||||
|
||||
FilterBar::FilterBar(tr_session* session, Glib::RefPtr<Gtk::TreeModel> const& tmodel)
|
||||
: Gtk::Box(Gtk::ORIENTATION_HORIZONTAL, GUI_PAD_SMALL)
|
||||
FilterBarExtraInit::FilterBarExtraInit()
|
||||
: ExtraClassInit(&FilterBarExtraInit::class_init, nullptr, &FilterBarExtraInit::instance_init)
|
||||
{
|
||||
}
|
||||
|
||||
void FilterBarExtraInit::class_init(void* klass, void* /*user_data*/)
|
||||
{
|
||||
auto* const widget_klass = GTK_WIDGET_CLASS(klass);
|
||||
|
||||
gtk_widget_class_set_template_from_resource(widget_klass, gtr_get_full_resource_path("FilterBar.ui").c_str());
|
||||
|
||||
gtk_widget_class_bind_template_child_full(widget_klass, "activity_combo", FALSE, 0);
|
||||
gtk_widget_class_bind_template_child_full(widget_klass, "tracker_combo", FALSE, 0);
|
||||
gtk_widget_class_bind_template_child_full(widget_klass, "text_entry", FALSE, 0);
|
||||
gtk_widget_class_bind_template_child_full(widget_klass, "show_label", FALSE, 0);
|
||||
}
|
||||
|
||||
void FilterBarExtraInit::instance_init(GTypeInstance* instance, void* /*klass*/)
|
||||
{
|
||||
gtk_widget_init_template(GTK_WIDGET(instance));
|
||||
}
|
||||
|
||||
/***
|
||||
****
|
||||
***/
|
||||
|
||||
FilterBar::FilterBar()
|
||||
: Glib::ObjectBase(typeid(FilterBar))
|
||||
{
|
||||
}
|
||||
|
||||
FilterBar::FilterBar(
|
||||
BaseObjectType* cast_item,
|
||||
Glib::RefPtr<Gtk::Builder> const& /*builder*/,
|
||||
tr_session* session,
|
||||
Glib::RefPtr<Gtk::TreeModel> const& tmodel)
|
||||
: Glib::ObjectBase(typeid(FilterBar))
|
||||
, Gtk::Box(cast_item)
|
||||
, impl_(std::make_unique<Impl>(*this, session, tmodel))
|
||||
{
|
||||
}
|
||||
|
||||
FilterBar::~FilterBar() = default;
|
||||
|
||||
FilterBar::Impl::Impl(FilterBar& widget, tr_session* session, Glib::RefPtr<Gtk::TreeModel> const& tmodel)
|
||||
: widget_(widget)
|
||||
, activity_(get_template_child<Gtk::ComboBox>("activity_combo"))
|
||||
, tracker_(get_template_child<Gtk::ComboBox>("tracker_combo"))
|
||||
, entry_(get_template_child<Gtk::Entry>("text_entry"))
|
||||
, show_lb_(get_template_child<Gtk::Label>("show_label"))
|
||||
{
|
||||
show_lb_ = Gtk::make_managed<Gtk::Label>();
|
||||
activity_ = activity_combo_box_new(tmodel);
|
||||
tracker_ = tracker_combo_box_new(tmodel);
|
||||
activity_combo_box_init(activity_, tmodel);
|
||||
tracker_combo_box_init(tracker_, tmodel);
|
||||
|
||||
filter_model_ = Gtk::TreeModelFilter::create(tmodel);
|
||||
filter_model_->signal_row_deleted().connect([this](auto const& /*path*/) { update_count_label_idle(); });
|
||||
filter_model_->signal_row_inserted().connect([this](auto const& /*path*/, auto const& /*iter*/)
|
||||
{ update_count_label_idle(); });
|
||||
|
||||
tracker_->property_width_request() = 170;
|
||||
static_cast<Gtk::TreeStore*>(gtr_get_ptr(tracker_->get_model()))->set_data(SESSION_KEY, session);
|
||||
|
||||
filter_model_->set_visible_func(sigc::mem_fun(*this, &Impl::is_row_visible));
|
||||
|
@ -756,30 +798,13 @@ FilterBar::Impl::Impl(FilterBar& widget, tr_session* session, Glib::RefPtr<Gtk::
|
|||
tracker_->signal_changed().connect(sigc::mem_fun(*this, &Impl::selection_changed_cb));
|
||||
activity_->signal_changed().connect(sigc::mem_fun(*this, &Impl::selection_changed_cb));
|
||||
|
||||
/* add the activity combobox */
|
||||
show_lb_->set_mnemonic_widget(*activity_);
|
||||
widget_.pack_start(*show_lb_, false, false, 0);
|
||||
widget_.pack_start(*activity_, true, true, 0);
|
||||
activity_->set_margin_end(GUI_PAD);
|
||||
|
||||
/* add the tracker combobox */
|
||||
widget_.pack_start(*tracker_, true, true, 0);
|
||||
tracker_->set_margin_end(GUI_PAD);
|
||||
|
||||
/* add the entry field */
|
||||
entry_ = Gtk::make_managed<Gtk::Entry>();
|
||||
entry_->set_icon_from_icon_name("edit-clear", Gtk::ENTRY_ICON_SECONDARY);
|
||||
entry_->signal_icon_release().connect([this](auto /*icon_position*/, auto const* /*event*/) { entry_->set_text({}); });
|
||||
widget_.pack_start(*entry_, true, true, 0);
|
||||
|
||||
entry_->signal_changed().connect(sigc::mem_fun(*this, &Impl::filter_entry_changed));
|
||||
selection_changed_cb();
|
||||
|
||||
selection_changed_cb();
|
||||
update_count_label();
|
||||
}
|
||||
|
||||
FilterBar::~FilterBar() = default;
|
||||
|
||||
FilterBar::Impl::~Impl()
|
||||
{
|
||||
torrent_model_row_deleted_cb_tag_.disconnect();
|
||||
|
@ -800,3 +825,13 @@ Glib::RefPtr<Gtk::TreeModel> FilterBar::Impl::get_filter_model() const
|
|||
{
|
||||
return filter_model_;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
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)));
|
||||
}
|
||||
|
|
|
@ -7,16 +7,34 @@
|
|||
|
||||
#include <memory>
|
||||
|
||||
#include <glibmm/extraclassinit.h>
|
||||
#include <gtkmm.h>
|
||||
|
||||
#include <libtransmission/tr-macros.h>
|
||||
|
||||
typedef struct tr_session tr_session;
|
||||
|
||||
class FilterBar : public Gtk::Box
|
||||
class FilterBarExtraInit : public Glib::ExtraClassInit
|
||||
{
|
||||
public:
|
||||
FilterBar(tr_session* session, Glib::RefPtr<Gtk::TreeModel> const& torrent_model);
|
||||
FilterBarExtraInit();
|
||||
|
||||
private:
|
||||
static void class_init(void* klass, void* user_data);
|
||||
static void instance_init(GTypeInstance* instance, void* klass);
|
||||
};
|
||||
|
||||
class FilterBar
|
||||
: public FilterBarExtraInit
|
||||
, public Gtk::Box
|
||||
{
|
||||
public:
|
||||
FilterBar();
|
||||
FilterBar(
|
||||
BaseObjectType* cast_item,
|
||||
Glib::RefPtr<Gtk::Builder> const& builder,
|
||||
tr_session* session,
|
||||
Glib::RefPtr<Gtk::TreeModel> const& torrent_model);
|
||||
~FilterBar() override;
|
||||
|
||||
TR_DISABLE_COPY_MOVE(FilterBar)
|
||||
|
|
|
@ -0,0 +1,62 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Generated with glade 3.38.2 -->
|
||||
<interface domain="transmission-gtk">
|
||||
<requires lib="gtk+" version="3.24"/>
|
||||
<template class="gtkmm__CustomObject_9FilterBar" parent="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="border-width">3</property>
|
||||
<property name="spacing">3</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="show_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="label" translatable="yes">_Show:</property>
|
||||
<property name="use-underline">True</property>
|
||||
<property name="mnemonic-widget">activity_combo</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkComboBox" id="activity_combo">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="margin-end">6</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkComboBox" id="tracker_combo">
|
||||
<property name="width-request">170</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="margin-end">6</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkEntry" id="text_entry">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="secondary-icon-name">edit-clear</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
</template>
|
||||
</interface>
|
|
@ -61,6 +61,16 @@ FreeSpaceLabel::FreeSpaceLabel(Glib::RefPtr<Session> const& core, std::string_vi
|
|||
{
|
||||
}
|
||||
|
||||
FreeSpaceLabel::FreeSpaceLabel(
|
||||
BaseObjectType* cast_item,
|
||||
Glib::RefPtr<Gtk::Builder> const& /*builder*/,
|
||||
Glib::RefPtr<Session> const& core,
|
||||
std::string_view dir)
|
||||
: Gtk::Label(cast_item)
|
||||
, impl_(std::make_unique<Impl>(*this, core, dir))
|
||||
{
|
||||
}
|
||||
|
||||
FreeSpaceLabel::~FreeSpaceLabel() = default;
|
||||
|
||||
FreeSpaceLabel::Impl::Impl(FreeSpaceLabel& label, Glib::RefPtr<Session> const& core, std::string_view dir)
|
||||
|
|
|
@ -17,6 +17,11 @@ class FreeSpaceLabel : public Gtk::Label
|
|||
{
|
||||
public:
|
||||
FreeSpaceLabel(Glib::RefPtr<Session> const& core, std::string_view dir = {});
|
||||
FreeSpaceLabel(
|
||||
BaseObjectType* cast_item,
|
||||
Glib::RefPtr<Gtk::Builder> const& builder,
|
||||
Glib::RefPtr<Session> const& core,
|
||||
std::string_view dir = {});
|
||||
~FreeSpaceLabel() override;
|
||||
|
||||
TR_DISABLE_COPY_MOVE(FreeSpaceLabel)
|
||||
|
|
|
@ -9,11 +9,11 @@
|
|||
#include <glibmm/i18n.h>
|
||||
|
||||
#include <libtransmission/transmission.h>
|
||||
#include <libtransmission/utils.h> /* tr_formatter_speed_KBps() */
|
||||
#include <libtransmission/utils.h> // tr_formatter_speed_KBps()
|
||||
|
||||
#include "Actions.h"
|
||||
#include "FilterBar.h"
|
||||
#include "HigWorkarea.h"
|
||||
#include "HigWorkarea.h" // GUI_PAD_SMALL
|
||||
#include "MainWindow.h"
|
||||
#include "Prefs.h"
|
||||
#include "PrefsDialog.h"
|
||||
|
@ -24,7 +24,11 @@
|
|||
class MainWindow::Impl
|
||||
{
|
||||
public:
|
||||
Impl(MainWindow& window, Glib::RefPtr<Gio::ActionGroup> const& actions, Glib::RefPtr<Session> const& core);
|
||||
Impl(
|
||||
MainWindow& window,
|
||||
Glib::RefPtr<Gtk::Builder> const& builder,
|
||||
Glib::RefPtr<Gio::ActionGroup> const& actions,
|
||||
Glib::RefPtr<Session> const& core);
|
||||
~Impl();
|
||||
|
||||
TR_DISABLE_COPY_MOVE(Impl)
|
||||
|
@ -36,7 +40,7 @@ public:
|
|||
void prefsChanged(tr_quark key);
|
||||
|
||||
private:
|
||||
Gtk::TreeView* makeview(Glib::RefPtr<Gtk::TreeModel> const& model);
|
||||
void init_view(Gtk::TreeView* view, Glib::RefPtr<Gtk::TreeModel> const& model);
|
||||
|
||||
Gtk::Menu* createOptionsMenu();
|
||||
Gtk::Menu* createSpeedMenu(tr_direction dir);
|
||||
|
@ -63,6 +67,7 @@ private:
|
|||
|
||||
private:
|
||||
MainWindow& window_;
|
||||
Glib::RefPtr<Session> const core_;
|
||||
|
||||
std::array<Gtk::RadioMenuItem*, 2> speedlimit_on_item_;
|
||||
std::array<Gtk::RadioMenuItem*, 2> speedlimit_off_item_;
|
||||
|
@ -70,9 +75,9 @@ private:
|
|||
Gtk::RadioMenuItem* ratio_off_item_ = nullptr;
|
||||
Gtk::ScrolledWindow* scroll_ = nullptr;
|
||||
Gtk::TreeView* view_ = nullptr;
|
||||
Gtk::Toolbar* toolbar_ = nullptr;
|
||||
FilterBar* filter_ = nullptr;
|
||||
Gtk::Grid* status_ = nullptr;
|
||||
Gtk::Widget* toolbar_ = nullptr;
|
||||
FilterBar* filter_;
|
||||
Gtk::Widget* status_ = nullptr;
|
||||
Gtk::Menu* status_menu_;
|
||||
Gtk::Label* ul_lb_ = nullptr;
|
||||
Gtk::Label* dl_lb_ = nullptr;
|
||||
|
@ -80,10 +85,8 @@ private:
|
|||
Gtk::Image* alt_speed_image_ = nullptr;
|
||||
Gtk::ToggleButton* alt_speed_button_ = nullptr;
|
||||
Gtk::Menu* options_menu_ = nullptr;
|
||||
Glib::RefPtr<Gtk::TreeSelection> selection_;
|
||||
TorrentCellRenderer* renderer_ = nullptr;
|
||||
Gtk::TreeViewColumn* column_ = nullptr;
|
||||
Glib::RefPtr<Session> const core_;
|
||||
sigc::connection pref_handler_id_;
|
||||
Gtk::Menu* popup_menu_ = nullptr;
|
||||
};
|
||||
|
@ -118,20 +121,12 @@ bool tree_view_search_equal_func(
|
|||
|
||||
} // namespace
|
||||
|
||||
Gtk::TreeView* MainWindow::Impl::makeview(Glib::RefPtr<Gtk::TreeModel> const& model)
|
||||
void MainWindow::Impl::init_view(Gtk::TreeView* view, Glib::RefPtr<Gtk::TreeModel> const& model)
|
||||
{
|
||||
auto* view = Gtk::make_managed<Gtk::TreeView>();
|
||||
view->set_search_column(torrent_cols.name_collated);
|
||||
view->set_search_equal_func(&tree_view_search_equal_func);
|
||||
view->set_headers_visible(false);
|
||||
view->set_fixed_height_mode(true);
|
||||
|
||||
selection_ = view->get_selection();
|
||||
|
||||
column_ = Gtk::make_managed<Gtk::TreeViewColumn>();
|
||||
column_->set_title(_("Torrent"));
|
||||
column_->set_resizable(true);
|
||||
column_->set_sizing(Gtk::TREE_VIEW_COLUMN_FIXED);
|
||||
column_ = view->get_column(0);
|
||||
|
||||
renderer_ = Gtk::make_managed<TorrentCellRenderer>();
|
||||
column_->pack_start(*renderer_, false);
|
||||
|
@ -139,12 +134,9 @@ Gtk::TreeView* MainWindow::Impl::makeview(Glib::RefPtr<Gtk::TreeModel> const& mo
|
|||
column_->add_attribute(renderer_->property_piece_upload_speed(), torrent_cols.speed_up);
|
||||
column_->add_attribute(renderer_->property_piece_download_speed(), torrent_cols.speed_down);
|
||||
|
||||
view->append_column(*column_);
|
||||
renderer_->property_xpad() = GUI_PAD_SMALL;
|
||||
renderer_->property_ypad() = GUI_PAD_SMALL;
|
||||
|
||||
selection_->set_mode(Gtk::SELECTION_MULTIPLE);
|
||||
|
||||
view->signal_popup_menu().connect_notify([this]() { on_popup_menu(nullptr); });
|
||||
view->signal_button_press_event().connect(
|
||||
[this, view](GdkEventButton* event)
|
||||
|
@ -156,8 +148,6 @@ Gtk::TreeView* MainWindow::Impl::makeview(Glib::RefPtr<Gtk::TreeModel> const& mo
|
|||
{ gtr_action_activate("show-torrent-properties"); });
|
||||
|
||||
view->set_model(model);
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
void MainWindow::Impl::prefsChanged(tr_quark const key)
|
||||
|
@ -395,21 +385,41 @@ std::unique_ptr<MainWindow> MainWindow::create(
|
|||
Glib::RefPtr<Gio::ActionGroup> const& actions,
|
||||
Glib::RefPtr<Session> const& core)
|
||||
{
|
||||
return std::unique_ptr<MainWindow>(new MainWindow(app, actions, core));
|
||||
auto const builder = Gtk::Builder::create_from_resource(gtr_get_full_resource_path("MainWindow.ui"));
|
||||
return std::unique_ptr<MainWindow>(gtr_get_widget_derived<MainWindow>(builder, "MainWindow", app, actions, core));
|
||||
}
|
||||
|
||||
MainWindow::MainWindow(Gtk::Application& app, Glib::RefPtr<Gio::ActionGroup> const& actions, Glib::RefPtr<Session> const& core)
|
||||
: Gtk::ApplicationWindow()
|
||||
, impl_(std::make_unique<Impl>(*this, actions, core))
|
||||
MainWindow::MainWindow(
|
||||
BaseObjectType* cast_item,
|
||||
Glib::RefPtr<Gtk::Builder> const& builder,
|
||||
Gtk::Application& app,
|
||||
Glib::RefPtr<Gio::ActionGroup> const& actions,
|
||||
Glib::RefPtr<Session> const& core)
|
||||
: Gtk::ApplicationWindow(cast_item)
|
||||
, impl_(std::make_unique<Impl>(*this, builder, actions, core))
|
||||
{
|
||||
app.add_window(*this);
|
||||
}
|
||||
|
||||
MainWindow::~MainWindow() = default;
|
||||
|
||||
MainWindow::Impl::Impl(MainWindow& window, Glib::RefPtr<Gio::ActionGroup> const& actions, Glib::RefPtr<Session> const& core)
|
||||
MainWindow::Impl::Impl(
|
||||
MainWindow& window,
|
||||
Glib::RefPtr<Gtk::Builder> const& builder,
|
||||
Glib::RefPtr<Gio::ActionGroup> const& actions,
|
||||
Glib::RefPtr<Session> const& core)
|
||||
: window_(window)
|
||||
, core_(core)
|
||||
, scroll_(gtr_get_widget<Gtk::ScrolledWindow>(builder, "torrents_view_scroll"))
|
||||
, view_(gtr_get_widget<Gtk::TreeView>(builder, "torrents_view"))
|
||||
, toolbar_(gtr_get_widget<Gtk::Widget>(builder, "toolbar"))
|
||||
, filter_(gtr_get_widget_derived<FilterBar>(builder, "filterbar", core_->get_session(), core_->get_model()))
|
||||
, status_(gtr_get_widget<Gtk::Widget>(builder, "statusbar"))
|
||||
, ul_lb_(gtr_get_widget<Gtk::Label>(builder, "upload_speed_label"))
|
||||
, dl_lb_(gtr_get_widget<Gtk::Label>(builder, "download_speed_label"))
|
||||
, stats_lb_(gtr_get_widget<Gtk::Label>(builder, "statistics_label"))
|
||||
, alt_speed_image_(gtr_get_widget<Gtk::Image>(builder, "alt_speed_button_image"))
|
||||
, alt_speed_button_(gtr_get_widget<Gtk::ToggleButton>(builder, "alt_speed_button"))
|
||||
{
|
||||
static struct
|
||||
{
|
||||
|
@ -424,7 +434,6 @@ MainWindow::Impl::Impl(MainWindow& window, Glib::RefPtr<Gio::ActionGroup> const&
|
|||
|
||||
/* make the window */
|
||||
window.set_title(Glib::get_application_name());
|
||||
window.set_role("tr-main");
|
||||
window.set_default_size(gtr_pref_int_get(TR_KEY_main_window_width), gtr_pref_int_get(TR_KEY_main_window_height));
|
||||
window.move(gtr_pref_int_get(TR_KEY_main_window_x), gtr_pref_int_get(TR_KEY_main_window_y));
|
||||
|
||||
|
@ -434,27 +443,6 @@ MainWindow::Impl::Impl(MainWindow& window, Glib::RefPtr<Gio::ActionGroup> const&
|
|||
}
|
||||
|
||||
window.insert_action_group("win", actions);
|
||||
/* Add style provider to the window. */
|
||||
/* Please move it to separate .css file if you’re adding more styles here. */
|
||||
auto const* style = ".tr-workarea.frame {border-left-width: 0; border-right-width: 0; border-radius: 0;}";
|
||||
auto css_provider = Gtk::CssProvider::create();
|
||||
css_provider->load_from_data(style);
|
||||
Gtk::StyleContext::add_provider_for_screen(
|
||||
Gdk::Screen::get_default(),
|
||||
css_provider,
|
||||
GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
|
||||
|
||||
/* window's main container */
|
||||
auto* vbox = Gtk::make_managed<Gtk::Box>(Gtk::ORIENTATION_VERTICAL, 0);
|
||||
window.add(*vbox);
|
||||
|
||||
/* toolbar */
|
||||
toolbar_ = gtr_action_get_widget<Gtk::Toolbar>("main-window-toolbar");
|
||||
toolbar_->get_style_context()->add_class(GTK_STYLE_CLASS_PRIMARY_TOOLBAR);
|
||||
|
||||
/* filter */
|
||||
filter_ = Gtk::make_managed<FilterBar>(core_->get_session(), core_->get_model());
|
||||
filter_->set_border_width(GUI_PAD_SMALL);
|
||||
|
||||
/* status menu */
|
||||
status_menu_ = Gtk::make_managed<Gtk::Menu>();
|
||||
|
@ -474,73 +462,23 @@ MainWindow::Impl::Impl(MainWindow& window, Glib::RefPtr<Gio::ActionGroup> const&
|
|||
*** Statusbar
|
||||
**/
|
||||
|
||||
status_ = Gtk::make_managed<Gtk::Grid>();
|
||||
status_->set_orientation(Gtk::ORIENTATION_HORIZONTAL);
|
||||
status_->set_border_width(GUI_PAD_SMALL);
|
||||
|
||||
/* gear */
|
||||
auto* gear_button = Gtk::make_managed<Gtk::Button>();
|
||||
gear_button->add(*Gtk::make_managed<Gtk::Image>("options-symbolic", Gtk::ICON_SIZE_MENU));
|
||||
gear_button->set_tooltip_text(_("Options"));
|
||||
gear_button->set_relief(Gtk::RELIEF_NONE);
|
||||
auto* gear_button = gtr_get_widget<Gtk::Button>(builder, "gear_button");
|
||||
options_menu_ = createOptionsMenu();
|
||||
gear_button->signal_clicked().connect([this, gear_button]() { onOptionsClicked(gear_button); });
|
||||
status_->add(*gear_button);
|
||||
|
||||
/* turtle */
|
||||
alt_speed_image_ = Gtk::make_managed<Gtk::Image>();
|
||||
alt_speed_button_ = Gtk::make_managed<Gtk::ToggleButton>();
|
||||
alt_speed_button_->set_image(*alt_speed_image_);
|
||||
alt_speed_button_->set_relief(Gtk::RELIEF_NONE);
|
||||
alt_speed_button_->signal_toggled().connect(sigc::mem_fun(*this, &Impl::alt_speed_toggled_cb));
|
||||
status_->add(*alt_speed_button_);
|
||||
|
||||
/* spacer */
|
||||
auto* w = Gtk::make_managed<Gtk::Fixed>();
|
||||
w->set_hexpand(true);
|
||||
status_->add(*w);
|
||||
|
||||
/* download */
|
||||
dl_lb_ = Gtk::make_managed<Gtk::Label>();
|
||||
dl_lb_->set_single_line_mode(true);
|
||||
status_->add(*dl_lb_);
|
||||
|
||||
/* upload */
|
||||
ul_lb_ = Gtk::make_managed<Gtk::Label>();
|
||||
ul_lb_->set_margin_start(GUI_PAD);
|
||||
ul_lb_->set_single_line_mode(true);
|
||||
status_->add(*ul_lb_);
|
||||
|
||||
/* ratio */
|
||||
stats_lb_ = Gtk::make_managed<Gtk::Label>();
|
||||
stats_lb_->set_margin_start(GUI_PAD_BIG);
|
||||
stats_lb_->set_single_line_mode(true);
|
||||
status_->add(*stats_lb_);
|
||||
|
||||
/* ratio selector */
|
||||
auto* ratio_button = Gtk::make_managed<Gtk::Button>();
|
||||
ratio_button->set_tooltip_text(_("Statistics"));
|
||||
ratio_button->add(*Gtk::make_managed<Gtk::Image>("ratio-symbolic", Gtk::ICON_SIZE_MENU));
|
||||
ratio_button->set_relief(Gtk::RELIEF_NONE);
|
||||
auto* ratio_button = gtr_get_widget<Gtk::Button>(builder, "ratio_button");
|
||||
ratio_button->signal_clicked().connect([this, ratio_button]() { onYinYangClicked(ratio_button); });
|
||||
status_->add(*ratio_button);
|
||||
|
||||
/**
|
||||
*** Workarea
|
||||
**/
|
||||
|
||||
view_ = makeview(filter_->get_filter_model());
|
||||
scroll_ = Gtk::make_managed<Gtk::ScrolledWindow>();
|
||||
scroll_->set_policy(Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
|
||||
scroll_->set_shadow_type(Gtk::SHADOW_OUT);
|
||||
scroll_->get_style_context()->add_class("tr-workarea");
|
||||
scroll_->add(*view_);
|
||||
|
||||
/* lay out the widgets */
|
||||
vbox->pack_start(*toolbar_, false, false);
|
||||
vbox->pack_start(*filter_, false, false);
|
||||
vbox->pack_start(*scroll_, true, true);
|
||||
vbox->pack_start(*status_, false, false);
|
||||
init_view(view_, filter_->get_filter_model());
|
||||
|
||||
{
|
||||
/* this is to determine the maximum width/height for the label */
|
||||
|
@ -550,15 +488,8 @@ MainWindow::Impl::Impl(MainWindow& window, Glib::RefPtr<Gio::ActionGroup> const&
|
|||
pango_layout->get_pixel_size(width, height);
|
||||
ul_lb_->set_size_request(width, height);
|
||||
dl_lb_->set_size_request(width, height);
|
||||
ul_lb_->set_halign(Gtk::ALIGN_END);
|
||||
ul_lb_->set_valign(Gtk::ALIGN_CENTER);
|
||||
dl_lb_->set_halign(Gtk::ALIGN_END);
|
||||
dl_lb_->set_valign(Gtk::ALIGN_CENTER);
|
||||
}
|
||||
|
||||
/* show all but the window */
|
||||
vbox->show_all();
|
||||
|
||||
/* listen for prefs changes that affect the window */
|
||||
prefsChanged(TR_KEY_compact_view);
|
||||
prefsChanged(TR_KEY_show_filterbar);
|
||||
|
@ -670,7 +601,7 @@ Glib::RefPtr<Gtk::TreeSelection> MainWindow::get_selection() const
|
|||
|
||||
Glib::RefPtr<Gtk::TreeSelection> MainWindow::Impl::get_selection() const
|
||||
{
|
||||
return selection_;
|
||||
return view_->get_selection();
|
||||
}
|
||||
|
||||
void MainWindow::set_busy(bool isBusy)
|
||||
|
|
|
@ -16,6 +16,12 @@ class Session;
|
|||
class MainWindow : public Gtk::ApplicationWindow
|
||||
{
|
||||
public:
|
||||
MainWindow(
|
||||
BaseObjectType* cast_item,
|
||||
Glib::RefPtr<Gtk::Builder> const& builder,
|
||||
Gtk::Application& app,
|
||||
Glib::RefPtr<Gio::ActionGroup> const& actions,
|
||||
Glib::RefPtr<Session> const& core);
|
||||
~MainWindow() override;
|
||||
|
||||
TR_DISABLE_COPY_MOVE(MainWindow)
|
||||
|
@ -30,9 +36,6 @@ public:
|
|||
void set_busy(bool isBusy);
|
||||
void refresh();
|
||||
|
||||
protected:
|
||||
MainWindow(Gtk::Application& app, Glib::RefPtr<Gio::ActionGroup> const& actions, Glib::RefPtr<Session> const& core);
|
||||
|
||||
private:
|
||||
class Impl;
|
||||
std::unique_ptr<Impl> const impl_;
|
||||
|
|
|
@ -0,0 +1,293 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Generated with glade 3.38.2 -->
|
||||
<interface domain="transmission-gtk">
|
||||
<requires lib="gtk+" version="3.24"/>
|
||||
<object class="GtkApplicationWindow" id="MainWindow">
|
||||
<property name="can-focus">False</property>
|
||||
<property name="role">tr-main</property>
|
||||
<child>
|
||||
<object class="GtkBox" id="window_layout">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkToolbar" id="toolbar">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<child>
|
||||
<object class="GtkToolButton" id="open_file_button">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="tooltip-text" translatable="yes">Open a torrent</property>
|
||||
<property name="is-important">True</property>
|
||||
<property name="action-name">win.open-torrent</property>
|
||||
<property name="label" translatable="yes">_Open</property>
|
||||
<property name="use-underline">True</property>
|
||||
<property name="icon-name">document-open</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="homogeneous">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkToolButton" id="start_torrent_button">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="tooltip-text" translatable="yes">Start torrent</property>
|
||||
<property name="action-name">win.torrent-start</property>
|
||||
<property name="label" translatable="yes">_Start</property>
|
||||
<property name="use-underline">True</property>
|
||||
<property name="icon-name">media-playback-start</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="homogeneous">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkToolButton" id="pause_torrent_button">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="tooltip-text" translatable="yes">Pause torrent</property>
|
||||
<property name="action-name">win.torrent-stop</property>
|
||||
<property name="label" translatable="yes">_Pause</property>
|
||||
<property name="use-underline">True</property>
|
||||
<property name="icon-name">media-playback-pause</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="homogeneous">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkToolButton" id="remove_torrent_button">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="action-name">win.remove-torrent</property>
|
||||
<property name="label" translatable="yes">Remove torrent</property>
|
||||
<property name="use-underline">True</property>
|
||||
<property name="icon-name">list-remove</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="homogeneous">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSeparatorToolItem">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="homogeneous">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkToolButton" id="torrent_properties_button">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="tooltip-text" translatable="yes">Torrent properties</property>
|
||||
<property name="is-important">True</property>
|
||||
<property name="action-name">win.show-torrent-properties</property>
|
||||
<property name="label" translatable="yes">_Properties</property>
|
||||
<property name="use-underline">True</property>
|
||||
<property name="icon-name">document-properties</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="homogeneous">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="gtkmm__CustomObject_9FilterBar" id="filterbar">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow" id="torrents_view_scroll">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="hscrollbar-policy">never</property>
|
||||
<property name="shadow-type">out</property>
|
||||
<child>
|
||||
<object class="GtkTreeView" id="torrents_view">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="headers-visible">False</property>
|
||||
<property name="fixed-height-mode">True</property>
|
||||
<child internal-child="selection">
|
||||
<object class="GtkTreeSelection" id="torrents_view_selection">
|
||||
<property name="mode">multiple</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkTreeViewColumn" id="torrent_column">
|
||||
<property name="resizable">True</property>
|
||||
<property name="sizing">fixed</property>
|
||||
<property name="title" translatable="yes">Torrent</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<style>
|
||||
<class name="tr-workarea"/>
|
||||
</style>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox" id="statusbar">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="border-width">3</property>
|
||||
<property name="spacing">3</property>
|
||||
<child>
|
||||
<object class="GtkButton" id="gear_button">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="receives-default">True</property>
|
||||
<property name="tooltip-text" translatable="yes">Options</property>
|
||||
<property name="relief">none</property>
|
||||
<child>
|
||||
<object class="GtkImage" id="gear_button_image">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="icon-name">options-symbolic</property>
|
||||
<property name="icon_size">1</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkToggleButton" id="alt_speed_button">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="receives-default">True</property>
|
||||
<property name="relief">none</property>
|
||||
<child>
|
||||
<object class="GtkImage" id="alt_speed_button_image">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="icon-name">turtle-symbolic</property>
|
||||
<property name="icon_size">1</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkFixed">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="download_speed_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="margin-start">3</property>
|
||||
<property name="label">...</property>
|
||||
<property name="single-line-mode">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="upload_speed_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="margin-start">3</property>
|
||||
<property name="label">...</property>
|
||||
<property name="single-line-mode">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">4</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="ratio_button">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="receives-default">True</property>
|
||||
<property name="tooltip-text" translatable="yes">Statistics</property>
|
||||
<property name="relief">none</property>
|
||||
<child>
|
||||
<object class="GtkImage" id="ratio_button_image">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="icon-name">ratio-symbolic</property>
|
||||
<property name="icon_size">1</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="pack-type">end</property>
|
||||
<property name="position">5</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="statistics_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="margin-start">9</property>
|
||||
<property name="margin-end">3</property>
|
||||
<property name="label">...</property>
|
||||
<property name="single-line-mode">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">6</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">4</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</interface>
|
|
@ -21,7 +21,6 @@
|
|||
#include <libtransmission/makemeta.h>
|
||||
#include <libtransmission/utils.h> /* tr_formatter_mem_B() */
|
||||
|
||||
#include "HigWorkarea.h"
|
||||
#include "MakeDialog.h"
|
||||
#include "PrefsDialog.h"
|
||||
#include "Session.h"
|
||||
|
@ -38,10 +37,12 @@ class MakeProgressDialog : public Gtk::Dialog
|
|||
{
|
||||
public:
|
||||
MakeProgressDialog(
|
||||
BaseObjectType* cast_item,
|
||||
Glib::RefPtr<Gtk::Builder> const& builder,
|
||||
Gtk::Window& parent,
|
||||
tr_metainfo_builder& builder,
|
||||
tr_metainfo_builder& metainfo_builder,
|
||||
std::future<tr_error*> future,
|
||||
std::string_view target,
|
||||
std::string_view const& target,
|
||||
Glib::RefPtr<Session> const& core);
|
||||
~MakeProgressDialog() override;
|
||||
|
||||
|
@ -75,7 +76,7 @@ private:
|
|||
class MakeDialog::Impl
|
||||
{
|
||||
public:
|
||||
Impl(MakeDialog& dialog, Glib::RefPtr<Session> const& core);
|
||||
Impl(MakeDialog& dialog, Glib::RefPtr<Gtk::Builder> const& builder, Glib::RefPtr<Session> const& core);
|
||||
|
||||
TR_DISABLE_COPY_MOVE(Impl)
|
||||
|
||||
|
@ -237,48 +238,41 @@ void MakeProgressDialog::onProgressDialogResponse(int response)
|
|||
}
|
||||
|
||||
MakeProgressDialog::MakeProgressDialog(
|
||||
BaseObjectType* cast_item,
|
||||
Glib::RefPtr<Gtk::Builder> const& builder,
|
||||
Gtk::Window& parent,
|
||||
tr_metainfo_builder& builder,
|
||||
tr_metainfo_builder& metainfo_builder,
|
||||
std::future<tr_error*> future,
|
||||
std::string_view target,
|
||||
std::string_view const& target,
|
||||
Glib::RefPtr<Session> const& core)
|
||||
: Gtk::Dialog(_("New Torrent"), parent, true)
|
||||
, builder_{ builder }
|
||||
: Gtk::Dialog(cast_item)
|
||||
, builder_(metainfo_builder)
|
||||
, future_{ std::move(future) }
|
||||
, target_{ target }
|
||||
, core_{ core }
|
||||
, target_(target)
|
||||
, core_(core)
|
||||
, progress_label_(gtr_get_widget<Gtk::Label>(builder, "progress_label"))
|
||||
, progress_bar_(gtr_get_widget<Gtk::ProgressBar>(builder, "progress_bar"))
|
||||
{
|
||||
add_button(_("_Cancel"), Gtk::RESPONSE_CANCEL);
|
||||
add_button(_("_Close"), Gtk::RESPONSE_CLOSE);
|
||||
add_button(_("_Add"), Gtk::RESPONSE_ACCEPT);
|
||||
set_transient_for(parent);
|
||||
signal_response().connect(sigc::mem_fun(*this, &MakeProgressDialog::onProgressDialogResponse));
|
||||
|
||||
auto* fr = Gtk::make_managed<Gtk::Frame>();
|
||||
fr->set_border_width(GUI_PAD_BIG);
|
||||
fr->set_shadow_type(Gtk::SHADOW_NONE);
|
||||
auto* v = Gtk::make_managed<Gtk::Box>(Gtk::ORIENTATION_VERTICAL, GUI_PAD);
|
||||
fr->add(*v);
|
||||
|
||||
progress_label_ = Gtk::make_managed<Gtk::Label>(_("Creating torrent…"));
|
||||
progress_label_->set_halign(Gtk::ALIGN_START);
|
||||
progress_label_->set_valign(Gtk::ALIGN_CENTER);
|
||||
progress_label_->set_justify(Gtk::JUSTIFY_LEFT);
|
||||
v->pack_start(*progress_label_, false, false, 0);
|
||||
|
||||
progress_bar_ = Gtk::make_managed<Gtk::ProgressBar>();
|
||||
v->pack_start(*progress_bar_, false, false, 0);
|
||||
|
||||
progress_tag_ = Glib::signal_timeout().connect_seconds(
|
||||
sigc::mem_fun(*this, &MakeProgressDialog::onProgressDialogRefresh),
|
||||
SECONDARY_WINDOW_REFRESH_INTERVAL_SECONDS);
|
||||
onProgressDialogRefresh();
|
||||
|
||||
gtr_dialog_set_content(*this, *fr);
|
||||
}
|
||||
|
||||
void MakeDialog::Impl::makeProgressDialog(std::string_view target, std::future<tr_error*> future)
|
||||
{
|
||||
progress_dialog_ = std::make_unique<MakeProgressDialog>(dialog_, *builder_, std::move(future), target, core_);
|
||||
auto const builder = Gtk::Builder::create_from_resource(gtr_get_full_resource_path("MakeProgressDialog.ui"));
|
||||
progress_dialog_ = std::unique_ptr<MakeProgressDialog>(gtr_get_widget_derived<MakeProgressDialog>(
|
||||
builder,
|
||||
"MakeProgressDialog",
|
||||
dialog_,
|
||||
*builder_,
|
||||
std::move(future),
|
||||
target,
|
||||
core_));
|
||||
progress_dialog_->signal_hide().connect(
|
||||
[this]()
|
||||
{
|
||||
|
@ -350,7 +344,7 @@ void MakeDialog::Impl::updatePiecesLabel()
|
|||
{
|
||||
auto const filename = builder_ ? builder_->top() : ""sv;
|
||||
|
||||
auto gstr = Glib::ustring{ "<i>" };
|
||||
auto gstr = Glib::ustring();
|
||||
|
||||
if (std::empty(filename))
|
||||
{
|
||||
|
@ -373,8 +367,7 @@ void MakeDialog::Impl::updatePiecesLabel()
|
|||
fmt::arg("piece_size", tr_formatter_mem_B(builder_->pieceSize())));
|
||||
}
|
||||
|
||||
gstr += "</i>";
|
||||
pieces_lb_->set_markup(gstr);
|
||||
pieces_lb_->set_text(gstr);
|
||||
}
|
||||
|
||||
void MakeDialog::Impl::configurePieceSizeScale()
|
||||
|
@ -453,106 +446,69 @@ void MakeDialog::Impl::on_drag_data_received(
|
|||
drag_context->drag_finish(success, false, time_);
|
||||
}
|
||||
|
||||
std::unique_ptr<MakeDialog> MakeDialog::create(Gtk::Window& parent, Glib::RefPtr<Session> const& core)
|
||||
{
|
||||
return std::unique_ptr<MakeDialog>(new MakeDialog(parent, core));
|
||||
}
|
||||
|
||||
MakeDialog::MakeDialog(Gtk::Window& parent, Glib::RefPtr<Session> const& core)
|
||||
: Gtk::Dialog(_("New Torrent"), parent)
|
||||
, impl_(std::make_unique<Impl>(*this, core))
|
||||
MakeDialog::MakeDialog(
|
||||
BaseObjectType* cast_item,
|
||||
Glib::RefPtr<Gtk::Builder> const& builder,
|
||||
Gtk::Window& parent,
|
||||
Glib::RefPtr<Session> const& core)
|
||||
: Gtk::Dialog(cast_item)
|
||||
, impl_(std::make_unique<Impl>(*this, builder, core))
|
||||
{
|
||||
set_transient_for(parent);
|
||||
}
|
||||
|
||||
MakeDialog::~MakeDialog() = default;
|
||||
|
||||
MakeDialog::Impl::Impl(MakeDialog& dialog, Glib::RefPtr<Session> const& core)
|
||||
std::unique_ptr<MakeDialog> MakeDialog::create(Gtk::Window& parent, Glib::RefPtr<Session> const& core)
|
||||
{
|
||||
auto const builder = Gtk::Builder::create_from_resource(gtr_get_full_resource_path("MakeDialog.ui"));
|
||||
return std::unique_ptr<MakeDialog>(gtr_get_widget_derived<MakeDialog>(builder, "MakeDialog", parent, core));
|
||||
}
|
||||
|
||||
MakeDialog::Impl::Impl(MakeDialog& dialog, Glib::RefPtr<Gtk::Builder> const& builder, Glib::RefPtr<Session> const& core)
|
||||
: dialog_(dialog)
|
||||
, core_(core)
|
||||
, file_radio_(gtr_get_widget<Gtk::RadioButton>(builder, "source_file_radio"))
|
||||
, file_chooser_(gtr_get_widget<Gtk::FileChooserButton>(builder, "source_file_button"))
|
||||
, folder_radio_(gtr_get_widget<Gtk::RadioButton>(builder, "source_folder_radio"))
|
||||
, folder_chooser_(gtr_get_widget<Gtk::FileChooserButton>(builder, "source_folder_button"))
|
||||
, pieces_lb_(gtr_get_widget<Gtk::Label>(builder, "source_size_label"))
|
||||
, piece_size_scale_(gtr_get_widget<Gtk::Scale>(builder, "piece_size_scale"))
|
||||
, destination_chooser_(gtr_get_widget<Gtk::FileChooserButton>(builder, "destination_button"))
|
||||
, comment_check_(gtr_get_widget<Gtk::CheckButton>(builder, "comment_check"))
|
||||
, comment_entry_(gtr_get_widget<Gtk::Entry>(builder, "comment_entry"))
|
||||
, private_check_(gtr_get_widget<Gtk::CheckButton>(builder, "private_check"))
|
||||
, source_check_(gtr_get_widget<Gtk::CheckButton>(builder, "source_check"))
|
||||
, source_entry_(gtr_get_widget<Gtk::Entry>(builder, "source_entry"))
|
||||
, announce_text_buffer_(gtr_get_widget<Gtk::TextView>(builder, "trackers_view")->get_buffer())
|
||||
{
|
||||
guint row = 0;
|
||||
|
||||
dialog_.add_button(_("_Close"), Gtk::RESPONSE_CLOSE);
|
||||
dialog_.add_button(_("_New"), Gtk::RESPONSE_ACCEPT);
|
||||
dialog_.signal_response().connect(sigc::mem_fun(*this, &Impl::onResponse));
|
||||
|
||||
auto* t = Gtk::make_managed<HigWorkarea>();
|
||||
|
||||
t->add_section_title(row, _("Files"));
|
||||
|
||||
destination_chooser_ = Gtk::make_managed<Gtk::FileChooserButton>(Gtk::FILE_CHOOSER_ACTION_SELECT_FOLDER);
|
||||
destination_chooser_->set_current_folder(Glib::get_user_special_dir(Glib::USER_DIRECTORY_DESKTOP));
|
||||
t->add_row(row, _("Sa_ve to:"), *destination_chooser_);
|
||||
|
||||
Gtk::RadioButton::Group slist;
|
||||
|
||||
folder_radio_ = Gtk::make_managed<Gtk::RadioButton>(slist, _("Source F_older:"), true);
|
||||
folder_radio_->set_active(false);
|
||||
folder_chooser_ = Gtk::make_managed<Gtk::FileChooserButton>(Gtk::FILE_CHOOSER_ACTION_SELECT_FOLDER);
|
||||
folder_radio_->signal_toggled().connect([this]() { onSourceToggled2(folder_radio_, folder_chooser_); });
|
||||
folder_radio_->signal_toggled().connect([this]() { onSourceToggled(folder_radio_, folder_chooser_); });
|
||||
folder_chooser_->signal_selection_changed().connect([this]() { onChooserChosen(folder_chooser_); });
|
||||
folder_chooser_->set_sensitive(false);
|
||||
t->add_row_w(row, *folder_radio_, *folder_chooser_);
|
||||
|
||||
file_radio_ = Gtk::make_managed<Gtk::RadioButton>(slist, _("Source _File:"), true);
|
||||
file_radio_->set_active(true);
|
||||
file_chooser_ = Gtk::make_managed<Gtk::FileChooserButton>(Gtk::FILE_CHOOSER_ACTION_OPEN);
|
||||
file_radio_->signal_toggled().connect([this]() { onSourceToggled2(file_radio_, file_chooser_); });
|
||||
file_radio_->signal_toggled().connect([this]() { onSourceToggled(file_radio_, file_chooser_); });
|
||||
file_chooser_->signal_selection_changed().connect([this]() { onChooserChosen(file_chooser_); });
|
||||
t->add_row_w(row, *file_radio_, *file_chooser_);
|
||||
|
||||
pieces_lb_ = Gtk::make_managed<Gtk::Label>();
|
||||
pieces_lb_->set_markup(fmt::format(FMT_STRING("<i>{:s}</i>"), _("No source selected")));
|
||||
t->add_row(row, {}, *pieces_lb_);
|
||||
|
||||
piece_size_scale_ = Gtk::make_managed<Gtk::Scale>();
|
||||
piece_size_scale_->set_draw_value(false);
|
||||
piece_size_scale_->set_visible(false);
|
||||
piece_size_scale_->signal_value_changed().connect([this]() { onPieceSizeUpdated(); });
|
||||
t->add_row(row, _("Piece size:"), *piece_size_scale_);
|
||||
|
||||
t->add_section_divider(row);
|
||||
t->add_section_title(row, _("Properties"));
|
||||
|
||||
auto* v = Gtk::make_managed<Gtk::Box>(Gtk::ORIENTATION_VERTICAL, GUI_PAD_SMALL);
|
||||
announce_text_buffer_ = Gtk::TextBuffer::create();
|
||||
auto* w = Gtk::make_managed<Gtk::TextView>(announce_text_buffer_);
|
||||
w->set_size_request(-1, 80);
|
||||
auto* sw = Gtk::make_managed<Gtk::ScrolledWindow>();
|
||||
sw->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
|
||||
sw->add(*w);
|
||||
auto* fr = Gtk::make_managed<Gtk::Frame>();
|
||||
fr->set_shadow_type(Gtk::SHADOW_IN);
|
||||
fr->add(*sw);
|
||||
v->pack_start(*fr, true, true, 0);
|
||||
auto* l = Gtk::make_managed<Gtk::Label>();
|
||||
l->set_markup(_(
|
||||
"To add a backup URL, add it on the next line after a primary URL.\nTo add a new primary URL, add it after a blank line."));
|
||||
l->set_justify(Gtk::JUSTIFY_LEFT);
|
||||
l->set_halign(Gtk::ALIGN_START);
|
||||
l->set_valign(Gtk::ALIGN_CENTER);
|
||||
v->pack_start(*l, false, false, 0);
|
||||
t->add_tall_row(row, _("_Trackers:"), *v);
|
||||
|
||||
comment_check_ = Gtk::make_managed<Gtk::CheckButton>(_("Co_mment:"), true);
|
||||
comment_check_->set_active(false);
|
||||
comment_entry_ = Gtk::make_managed<Gtk::Entry>();
|
||||
comment_entry_->set_sensitive(false);
|
||||
comment_check_->signal_toggled().connect([this]() { onSourceToggled(comment_check_, comment_entry_); });
|
||||
t->add_row_w(row, *comment_check_, *comment_entry_);
|
||||
|
||||
source_check_ = Gtk::make_managed<Gtk::CheckButton>(_("_Source:"), true);
|
||||
source_check_->set_active(false);
|
||||
source_entry_ = Gtk::make_managed<Gtk::Entry>();
|
||||
source_entry_->set_sensitive(false);
|
||||
source_check_->signal_toggled().connect([this]() { onSourceToggled(source_check_, source_entry_); });
|
||||
t->add_row_w(row, *source_check_, *source_entry_);
|
||||
|
||||
private_check_ = t->add_wide_checkbutton(row, _("_Private torrent"), false);
|
||||
|
||||
gtr_dialog_set_content(dialog_, *t);
|
||||
|
||||
dialog_.drag_dest_set(Gtk::DEST_DEFAULT_ALL, Gdk::ACTION_COPY);
|
||||
dialog_.drag_dest_add_uri_targets();
|
||||
|
|
|
@ -16,15 +16,17 @@ class Session;
|
|||
class MakeDialog : public Gtk::Dialog
|
||||
{
|
||||
public:
|
||||
MakeDialog(
|
||||
BaseObjectType* cast_item,
|
||||
Glib::RefPtr<Gtk::Builder> const& builder,
|
||||
Gtk::Window& parent,
|
||||
Glib::RefPtr<Session> const& core);
|
||||
~MakeDialog() override;
|
||||
|
||||
TR_DISABLE_COPY_MOVE(MakeDialog)
|
||||
|
||||
static std::unique_ptr<MakeDialog> create(Gtk::Window& parent, Glib::RefPtr<Session> const& core);
|
||||
|
||||
protected:
|
||||
MakeDialog(Gtk::Window& parent, Glib::RefPtr<Session> const& core);
|
||||
|
||||
private:
|
||||
class Impl;
|
||||
std::unique_ptr<Impl> const impl_;
|
||||
|
|
|
@ -0,0 +1,429 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Generated with glade 3.38.2 -->
|
||||
<interface domain="transmission-gtk">
|
||||
<requires lib="gtk+" version="3.24"/>
|
||||
<object class="GtkDialog" id="MakeDialog">
|
||||
<property name="can-focus">False</property>
|
||||
<property name="border-width">6</property>
|
||||
<property name="title" translatable="yes">New Torrent</property>
|
||||
<property name="type-hint">dialog</property>
|
||||
<child internal-child="vbox">
|
||||
<object class="GtkBox" id="dialog_layout">
|
||||
<property name="can-focus">False</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">6</property>
|
||||
<child internal-child="action_area">
|
||||
<object class="GtkButtonBox" id="dialog_buttons">
|
||||
<property name="can-focus">False</property>
|
||||
<property name="layout-style">end</property>
|
||||
<child>
|
||||
<object class="GtkButton" id="close_button">
|
||||
<property name="label" translatable="yes">_Close</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="can-default">True</property>
|
||||
<property name="receives-default">True</property>
|
||||
<property name="use-underline">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="new_button">
|
||||
<property name="label" translatable="yes">_New</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="can-default">True</property>
|
||||
<property name="receives-default">True</property>
|
||||
<property name="use-underline">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox" id="dialog_content_layout">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">6</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="files_section_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="label" translatable="yes">Files</property>
|
||||
<property name="xalign">0</property>
|
||||
<attributes>
|
||||
<attribute name="weight" value="bold"/>
|
||||
</attributes>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<!-- n-columns=2 n-rows=5 -->
|
||||
<object class="GtkGrid" id="files_section_layout">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="margin-start">18</property>
|
||||
<property name="row-spacing">6</property>
|
||||
<property name="column-spacing">12</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="destination_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="label" translatable="yes">Sa_ve to:</property>
|
||||
<property name="use-underline">True</property>
|
||||
<property name="mnemonic-widget">destination_button</property>
|
||||
<property name="xalign">0</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkFileChooserButton" id="destination_button">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="action">select-folder</property>
|
||||
<property name="title" translatable="yes"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">1</property>
|
||||
<property name="top-attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkRadioButton" id="source_folder_radio">
|
||||
<property name="label" translatable="yes">Source F_older:</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="receives-default">False</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="use-underline">True</property>
|
||||
<property name="draw-indicator">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkFileChooserButton" id="source_folder_button">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="action">select-folder</property>
|
||||
<property name="title" translatable="yes"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">1</property>
|
||||
<property name="top-attach">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkRadioButton" id="source_file_radio">
|
||||
<property name="label" translatable="yes">Source _File:</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="receives-default">False</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="use-underline">True</property>
|
||||
<property name="active">True</property>
|
||||
<property name="draw-indicator">True</property>
|
||||
<property name="group">source_folder_radio</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkFileChooserButton" id="source_file_button">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="title" translatable="yes"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">1</property>
|
||||
<property name="top-attach">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="source_size_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="label" translatable="yes">No source selected</property>
|
||||
<property name="xalign">0</property>
|
||||
<attributes>
|
||||
<attribute name="style" value="italic"/>
|
||||
</attributes>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">1</property>
|
||||
<property name="top-attach">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="piece_size_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="label" translatable="yes">Piece size:</property>
|
||||
<property name="use-underline">True</property>
|
||||
<property name="mnemonic-widget">piece_size_scale</property>
|
||||
<property name="xalign">0</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">4</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkScale" id="piece_size_scale">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="digits">0</property>
|
||||
<property name="draw-value">False</property>
|
||||
<property name="value-pos">left</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">1</property>
|
||||
<property name="top-attach">4</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkFixed" id="properties_section_spacer">
|
||||
<property name="height-request">6</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="properties_section_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="label" translatable="yes">Properties</property>
|
||||
<property name="xalign">0</property>
|
||||
<attributes>
|
||||
<attribute name="weight" value="bold"/>
|
||||
</attributes>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<!-- n-columns=2 n-rows=4 -->
|
||||
<object class="GtkGrid" id="properties_section_layout">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="margin-start">18</property>
|
||||
<property name="row-spacing">6</property>
|
||||
<property name="column-spacing">12</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="trackers_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="valign">start</property>
|
||||
<property name="ypad">6</property>
|
||||
<property name="label" translatable="yes">_Trackers:</property>
|
||||
<property name="use-underline">True</property>
|
||||
<property name="mnemonic-widget">trackers_view</property>
|
||||
<property name="xalign">0</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox" id="trackers_layout">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="vexpand">True</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">3</property>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow" id="trackers_view_scroll">
|
||||
<property name="height-request">80</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="vexpand">True</property>
|
||||
<property name="shadow-type">in</property>
|
||||
<child>
|
||||
<object class="GtkTextView" id="trackers_view">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="accepts-tab">False</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="trackers_description_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="label" translatable="yes">To add a backup URL, add it on the next line after a primary URL.
|
||||
To add a new primary URL, add it after a blank line.</property>
|
||||
<property name="xalign">0</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">1</property>
|
||||
<property name="top-attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkCheckButton" id="comment_check">
|
||||
<property name="label" translatable="yes">Co_mment:</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="receives-default">False</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="use-underline">True</property>
|
||||
<property name="draw-indicator">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkEntry" id="comment_entry">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="hexpand">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">1</property>
|
||||
<property name="top-attach">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkCheckButton" id="source_check">
|
||||
<property name="label" translatable="yes">_Source:</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="receives-default">False</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="use-underline">True</property>
|
||||
<property name="draw-indicator">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkEntry" id="source_entry">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="hexpand">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">1</property>
|
||||
<property name="top-attach">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkCheckButton" id="private_check">
|
||||
<property name="label" translatable="yes">_Private torrent</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="receives-default">False</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="use-underline">True</property>
|
||||
<property name="draw-indicator">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">3</property>
|
||||
<property name="width">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">4</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<action-widgets>
|
||||
<action-widget response="-7">close_button</action-widget>
|
||||
<action-widget response="-3">new_button</action-widget>
|
||||
</action-widgets>
|
||||
</object>
|
||||
<object class="GtkSizeGroup" id="labels_width_group">
|
||||
<widgets>
|
||||
<widget name="destination_label"/>
|
||||
<widget name="source_folder_radio"/>
|
||||
<widget name="source_file_radio"/>
|
||||
<widget name="piece_size_label"/>
|
||||
<widget name="trackers_label"/>
|
||||
<widget name="comment_check"/>
|
||||
<widget name="source_check"/>
|
||||
</widgets>
|
||||
</object>
|
||||
</interface>
|
|
@ -0,0 +1,117 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Generated with glade 3.38.2 -->
|
||||
<interface domain="transmission-gtk">
|
||||
<requires lib="gtk+" version="3.24"/>
|
||||
<object class="GtkDialog" id="MakeProgressDialog">
|
||||
<property name="can-focus">False</property>
|
||||
<property name="border-width">6</property>
|
||||
<property name="title" translatable="yes">New Torrent</property>
|
||||
<property name="modal">True</property>
|
||||
<property name="type-hint">dialog</property>
|
||||
<child internal-child="vbox">
|
||||
<object class="GtkBox" id="dialog_layout">
|
||||
<property name="can-focus">False</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">6</property>
|
||||
<child internal-child="action_area">
|
||||
<object class="GtkButtonBox" id="dialog_button">
|
||||
<property name="can-focus">False</property>
|
||||
<property name="layout-style">end</property>
|
||||
<child>
|
||||
<object class="GtkButton" id="cancel_button">
|
||||
<property name="label" translatable="yes">_Cancel</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="can-default">True</property>
|
||||
<property name="receives-default">True</property>
|
||||
<property name="use-underline">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="close_button">
|
||||
<property name="label" translatable="yes">_Close</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="can-default">True</property>
|
||||
<property name="receives-default">True</property>
|
||||
<property name="use-underline">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="add_button">
|
||||
<property name="label" translatable="yes">_Add</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="can-default">True</property>
|
||||
<property name="receives-default">True</property>
|
||||
<property name="use-underline">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox" id="dialog_content_layout">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">6</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="progress_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="label" translatable="yes">Creating torrent…</property>
|
||||
<property name="xalign">0</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkProgressBar" id="progress_bar">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<action-widgets>
|
||||
<action-widget response="-6">cancel_button</action-widget>
|
||||
<action-widget response="-7">close_button</action-widget>
|
||||
<action-widget response="-3">add_button</action-widget>
|
||||
</action-widgets>
|
||||
</object>
|
||||
</interface>
|
|
@ -17,7 +17,6 @@
|
|||
#include <libtransmission/log.h>
|
||||
|
||||
#include "Actions.h"
|
||||
#include "HigWorkarea.h"
|
||||
#include "MessageLogWindow.h"
|
||||
#include "Prefs.h"
|
||||
#include "PrefsDialog.h"
|
||||
|
@ -46,7 +45,7 @@ MessageLogColumnsModel const message_log_cols;
|
|||
class MessageLogWindow::Impl
|
||||
{
|
||||
public:
|
||||
Impl(MessageLogWindow& window, Glib::RefPtr<Session> const& core);
|
||||
Impl(MessageLogWindow& window, Glib::RefPtr<Gtk::Builder> const& builder, Glib::RefPtr<Session> const& core);
|
||||
~Impl();
|
||||
|
||||
TR_DISABLE_COPY_MOVE(Impl)
|
||||
|
@ -59,19 +58,19 @@ private:
|
|||
void doSave(Gtk::Window& parent, Glib::ustring const& filename);
|
||||
|
||||
void onClearRequest();
|
||||
void onPauseToggled(Gtk::ToggleToolButton* w);
|
||||
void onPauseToggled(Gio::SimpleAction& action);
|
||||
|
||||
void scroll_to_bottom();
|
||||
void level_combo_changed_cb(Gtk::ComboBox* combo_box);
|
||||
Gtk::ComboBox* level_combo_new() const;
|
||||
void level_combo_init(Gtk::ComboBox* level_combo) const;
|
||||
|
||||
bool is_pinned_to_new() const;
|
||||
bool isRowVisible(Gtk::TreeModel::const_iterator const& iter) const;
|
||||
|
||||
private:
|
||||
MessageLogWindow& window_;
|
||||
|
||||
Glib::RefPtr<Session> const core_;
|
||||
|
||||
Gtk::TreeView* view_ = nullptr;
|
||||
Glib::RefPtr<Gtk::ListStore> store_;
|
||||
Glib::RefPtr<Gtk::TreeModelFilter> filter_;
|
||||
|
@ -139,16 +138,15 @@ void MessageLogWindow::Impl::scroll_to_bottom()
|
|||
*****
|
||||
****/
|
||||
|
||||
Gtk::ComboBox* MessageLogWindow::Impl::level_combo_new() const
|
||||
void MessageLogWindow::Impl::level_combo_init(Gtk::ComboBox* level_combo) const
|
||||
{
|
||||
auto items = std::vector<std::pair<Glib::ustring, int>>{};
|
||||
for (auto const& [level, name] : level_names_)
|
||||
{
|
||||
items.emplace_back(name, level);
|
||||
}
|
||||
auto* w = gtr_combo_box_new_enum(items);
|
||||
gtr_combo_box_set_active_enum(*w, gtr_pref_int_get(TR_KEY_message_level));
|
||||
return w;
|
||||
gtr_combo_box_set_enum(*level_combo, items);
|
||||
gtr_combo_box_set_active_enum(*level_combo, gtr_pref_int_get(TR_KEY_message_level));
|
||||
}
|
||||
|
||||
void MessageLogWindow::Impl::level_combo_changed_cb(Gtk::ComboBox* combo_box)
|
||||
|
@ -243,9 +241,14 @@ void MessageLogWindow::Impl::onClearRequest()
|
|||
myHead = myTail = nullptr;
|
||||
}
|
||||
|
||||
void MessageLogWindow::Impl::onPauseToggled(Gtk::ToggleToolButton* w)
|
||||
void MessageLogWindow::Impl::onPauseToggled(Gio::SimpleAction& action)
|
||||
{
|
||||
isPaused_ = w->get_active();
|
||||
bool value = false;
|
||||
action.get_state(value);
|
||||
|
||||
action.set_state(Glib::Variant<bool>::create(!value));
|
||||
|
||||
isPaused_ = !value;
|
||||
}
|
||||
|
||||
namespace
|
||||
|
@ -417,21 +420,31 @@ bool MessageLogWindow::Impl::onRefresh()
|
|||
|
||||
std::unique_ptr<MessageLogWindow> MessageLogWindow::create(Gtk::Window& parent, Glib::RefPtr<Session> const& core)
|
||||
{
|
||||
return std::unique_ptr<MessageLogWindow>(new MessageLogWindow(parent, core));
|
||||
auto const builder = Gtk::Builder::create_from_resource(gtr_get_full_resource_path("MessageLogWindow.ui"));
|
||||
return std::unique_ptr<MessageLogWindow>(
|
||||
gtr_get_widget_derived<MessageLogWindow>(builder, "MessageLogWindow", parent, core));
|
||||
}
|
||||
|
||||
MessageLogWindow::MessageLogWindow(Gtk::Window& parent, Glib::RefPtr<Session> const& core)
|
||||
: Gtk::Window(Gtk::WINDOW_TOPLEVEL)
|
||||
, impl_(std::make_unique<Impl>(*this, core))
|
||||
MessageLogWindow::MessageLogWindow(
|
||||
BaseObjectType* cast_item,
|
||||
Glib::RefPtr<Gtk::Builder> const& builder,
|
||||
Gtk::Window& parent,
|
||||
Glib::RefPtr<Session> const& core)
|
||||
: Gtk::Window(cast_item)
|
||||
, impl_(std::make_unique<Impl>(*this, builder, core))
|
||||
{
|
||||
set_transient_for(parent);
|
||||
}
|
||||
|
||||
MessageLogWindow::~MessageLogWindow() = default;
|
||||
|
||||
MessageLogWindow::Impl::Impl(MessageLogWindow& window, Glib::RefPtr<Session> const& core)
|
||||
MessageLogWindow::Impl::Impl(
|
||||
MessageLogWindow& window,
|
||||
Glib::RefPtr<Gtk::Builder> const& builder,
|
||||
Glib::RefPtr<Session> const& core)
|
||||
: window_(window)
|
||||
, core_(core)
|
||||
, view_(gtr_get_widget<Gtk::TreeView>(builder, "messages_view"))
|
||||
, level_names_{ { { TR_LOG_CRITICAL, _("Critical") },
|
||||
{ TR_LOG_ERROR, _("Error") },
|
||||
{ TR_LOG_WARN, _("Warning") },
|
||||
|
@ -439,73 +452,30 @@ MessageLogWindow::Impl::Impl(MessageLogWindow& window, Glib::RefPtr<Session> con
|
|||
{ TR_LOG_DEBUG, _("Debug") },
|
||||
{ TR_LOG_TRACE, _("Trace") } } }
|
||||
{
|
||||
window_.set_title(_("Message Log"));
|
||||
window_.set_default_size(560, 350);
|
||||
window_.set_role("message-log");
|
||||
auto* vbox = Gtk::make_managed<Gtk::Box>(Gtk::ORIENTATION_VERTICAL, 0);
|
||||
|
||||
/**
|
||||
*** toolbar
|
||||
**/
|
||||
|
||||
auto* toolbar = Gtk::make_managed<Gtk::Toolbar>();
|
||||
toolbar->set_toolbar_style(Gtk::TOOLBAR_BOTH_HORIZ);
|
||||
toolbar->get_style_context()->add_class(GTK_STYLE_CLASS_PRIMARY_TOOLBAR);
|
||||
auto const action_group = Gio::SimpleActionGroup::create();
|
||||
|
||||
{
|
||||
auto* icon = Gtk::make_managed<Gtk::Image>();
|
||||
icon->set_from_icon_name("document-save-as", Gtk::BuiltinIconSize::ICON_SIZE_SMALL_TOOLBAR);
|
||||
auto* item = Gtk::make_managed<Gtk::ToolButton>(*icon);
|
||||
item->set_is_important(true);
|
||||
item->set_label(_("Save _As"));
|
||||
item->set_use_underline(true);
|
||||
item->signal_clicked().connect(sigc::mem_fun(*this, &Impl::onSaveRequest));
|
||||
toolbar->insert(*item, -1);
|
||||
}
|
||||
auto const save_action = Gio::SimpleAction::create("save-message-log");
|
||||
save_action->signal_activate().connect([this](auto const& /*value*/) { onSaveRequest(); });
|
||||
action_group->add_action(save_action);
|
||||
|
||||
{
|
||||
auto* icon = Gtk::make_managed<Gtk::Image>();
|
||||
icon->set_from_icon_name("edit-clear", Gtk::BuiltinIconSize::ICON_SIZE_SMALL_TOOLBAR);
|
||||
auto* item = Gtk::make_managed<Gtk::ToolButton>(*icon);
|
||||
item->set_is_important(true);
|
||||
item->set_label(_("Clear"));
|
||||
item->set_use_underline(true);
|
||||
item->signal_clicked().connect(sigc::mem_fun(*this, &Impl::onClearRequest));
|
||||
toolbar->insert(*item, -1);
|
||||
}
|
||||
auto const clear_action = Gio::SimpleAction::create("clear-message-log");
|
||||
clear_action->signal_activate().connect([this](auto const& /*value*/) { onClearRequest(); });
|
||||
action_group->add_action(clear_action);
|
||||
|
||||
toolbar->insert(*Gtk::make_managed<Gtk::SeparatorToolItem>(), -1);
|
||||
auto const pause_action = Gio::SimpleAction::create_bool("pause-message-log");
|
||||
pause_action->signal_activate().connect([this, &action = *gtr_get_ptr(pause_action)](auto const& /*value*/)
|
||||
{ onPauseToggled(action); });
|
||||
action_group->add_action(pause_action);
|
||||
|
||||
{
|
||||
auto* icon = Gtk::make_managed<Gtk::Image>();
|
||||
icon->set_from_icon_name("media-playback-pause", Gtk::BuiltinIconSize::ICON_SIZE_SMALL_TOOLBAR);
|
||||
auto* item = Gtk::make_managed<Gtk::ToggleToolButton>(*icon);
|
||||
item->set_is_important(true);
|
||||
item->set_label(_("P_ause"));
|
||||
item->set_use_underline(true);
|
||||
item->signal_toggled().connect([this, item]() { onPauseToggled(item); });
|
||||
toolbar->insert(*item, -1);
|
||||
}
|
||||
auto* const level_combo = gtr_get_widget<Gtk::ComboBox>(builder, "level_combo");
|
||||
level_combo_init(level_combo);
|
||||
level_combo->signal_changed().connect([this, level_combo]() { level_combo_changed_cb(level_combo); });
|
||||
|
||||
toolbar->insert(*Gtk::make_managed<Gtk::SeparatorToolItem>(), -1);
|
||||
|
||||
{
|
||||
auto* w = Gtk::make_managed<Gtk::Label>(_("Level"));
|
||||
w->property_margin() = GUI_PAD;
|
||||
auto* item = Gtk::make_managed<Gtk::ToolItem>();
|
||||
item->add(*w);
|
||||
toolbar->insert(*item, -1);
|
||||
}
|
||||
|
||||
{
|
||||
auto* w = level_combo_new();
|
||||
w->signal_changed().connect([this, w]() { level_combo_changed_cb(w); });
|
||||
auto* item = Gtk::make_managed<Gtk::ToolItem>();
|
||||
item->add(*w);
|
||||
toolbar->insert(*item, -1);
|
||||
}
|
||||
|
||||
vbox->pack_start(*toolbar, false, false, 0);
|
||||
window_.insert_action_group("win", action_group);
|
||||
|
||||
/**
|
||||
*** messages
|
||||
|
@ -522,18 +492,12 @@ MessageLogWindow::Impl::Impl(MessageLogWindow& window, Glib::RefPtr<Session> con
|
|||
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_ = Gtk::make_managed<Gtk::TreeView>(sort_);
|
||||
view_->set_model(sort_);
|
||||
view_->signal_button_release_event().connect([this](GdkEventButton* event)
|
||||
{ return on_tree_view_button_released(view_, event); });
|
||||
appendColumn(view_, message_log_cols.sequence);
|
||||
appendColumn(view_, message_log_cols.name);
|
||||
appendColumn(view_, message_log_cols.message);
|
||||
auto* w = Gtk::make_managed<Gtk::ScrolledWindow>();
|
||||
w->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
|
||||
w->set_shadow_type(Gtk::SHADOW_IN);
|
||||
w->add(*view_);
|
||||
vbox->pack_start(*w, true, true, 0);
|
||||
window_.add(*vbox);
|
||||
|
||||
refresh_tag_ = Glib::signal_timeout().connect_seconds(
|
||||
sigc::mem_fun(*this, &Impl::onRefresh),
|
||||
|
|
|
@ -16,6 +16,11 @@ class Session;
|
|||
class MessageLogWindow : public Gtk::Window
|
||||
{
|
||||
public:
|
||||
MessageLogWindow(
|
||||
BaseObjectType* cast_item,
|
||||
Glib::RefPtr<Gtk::Builder> const& builder,
|
||||
Gtk::Window& parent,
|
||||
Glib::RefPtr<Session> const& core);
|
||||
~MessageLogWindow() override;
|
||||
|
||||
TR_DISABLE_COPY_MOVE(MessageLogWindow)
|
||||
|
@ -23,8 +28,6 @@ public:
|
|||
static std::unique_ptr<MessageLogWindow> create(Gtk::Window& parent, Glib::RefPtr<Session> const& core);
|
||||
|
||||
protected:
|
||||
MessageLogWindow(Gtk::Window& parent, Glib::RefPtr<Session> const& core);
|
||||
|
||||
void on_show() override;
|
||||
void on_hide() override;
|
||||
|
||||
|
|
|
@ -0,0 +1,163 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Generated with glade 3.38.2 -->
|
||||
<interface domain="transmission-gtk">
|
||||
<requires lib="gtk+" version="3.24"/>
|
||||
<object class="GtkWindow" id="MessageLogWindow">
|
||||
<property name="can-focus">False</property>
|
||||
<property name="title" translatable="yes">Message Log</property>
|
||||
<property name="role">message-log</property>
|
||||
<property name="default-width">560</property>
|
||||
<property name="default-height">350</property>
|
||||
<child>
|
||||
<object class="GtkBox" id="window_layout">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkToolbar" id="toolbar">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<child>
|
||||
<object class="GtkToolButton" id="save_as_button">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="is-important">True</property>
|
||||
<property name="action-name">win.save-message-log</property>
|
||||
<property name="label" translatable="yes">Save _As</property>
|
||||
<property name="use-underline">True</property>
|
||||
<property name="icon-name">document-save-as</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="homogeneous">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkToolButton" id="clear_button">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="is-important">True</property>
|
||||
<property name="action-name">win.clear-message-log</property>
|
||||
<property name="label" translatable="yes">Clear</property>
|
||||
<property name="use-underline">True</property>
|
||||
<property name="icon-name">edit-clear</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="homogeneous">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSeparatorToolItem">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="homogeneous">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkToggleToolButton" id="pause_button">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="is-important">True</property>
|
||||
<property name="action-name">win.pause-message-log</property>
|
||||
<property name="label" translatable="yes">P_ause</property>
|
||||
<property name="use-underline">True</property>
|
||||
<property name="icon-name">media-playback-pause</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="homogeneous">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSeparatorToolItem">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="homogeneous">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkToolItem" id="level_label_item">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="level_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="margin-start">6</property>
|
||||
<property name="margin-end">6</property>
|
||||
<property name="xpad">6</property>
|
||||
<property name="label" translatable="yes">Level</property>
|
||||
<property name="use-underline">True</property>
|
||||
<property name="mnemonic-widget">level_combo</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="homogeneous">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkToolItem" id="level_combo_item">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<child>
|
||||
<object class="GtkComboBox" id="level_combo">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<child>
|
||||
<object class="GtkCellRendererText" id="level_combo_renderer"/>
|
||||
<attributes>
|
||||
<attribute name="text">1</attribute>
|
||||
</attributes>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="homogeneous">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
<style>
|
||||
<class name="primary-toolbar"/>
|
||||
</style>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow" id="messages_view_scroll">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="shadow-type">in</property>
|
||||
<child>
|
||||
<object class="GtkTreeView" id="messages_view">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<child internal-child="selection">
|
||||
<object class="GtkTreeSelection" id="messages_view_selection"/>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</interface>
|
|
@ -14,7 +14,6 @@
|
|||
|
||||
#include "FileList.h"
|
||||
#include "FreeSpaceLabel.h"
|
||||
#include "HigWorkarea.h"
|
||||
#include "OptionsDialog.h"
|
||||
#include "Prefs.h"
|
||||
#include "PrefsDialog.h"
|
||||
|
@ -25,10 +24,45 @@
|
|||
*****
|
||||
****/
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
std::string get_source_file(tr_ctor& ctor)
|
||||
{
|
||||
if (char const* source_file = tr_ctorGetSourceFile(&ctor); source_file != nullptr)
|
||||
{
|
||||
return source_file;
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string get_download_dir(tr_ctor& ctor)
|
||||
{
|
||||
char const* str = nullptr;
|
||||
if (!tr_ctorGetDownloadDir(&ctor, TR_FORCE, &str))
|
||||
{
|
||||
g_assert_not_reached();
|
||||
}
|
||||
|
||||
g_assert(str != nullptr);
|
||||
return str;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
/****
|
||||
*****
|
||||
****/
|
||||
|
||||
class OptionsDialog::Impl
|
||||
{
|
||||
public:
|
||||
Impl(OptionsDialog& dialog, Glib::RefPtr<Session> const& core, std::unique_ptr<tr_ctor, void (*)(tr_ctor*)> ctor);
|
||||
Impl(
|
||||
OptionsDialog& dialog,
|
||||
Glib::RefPtr<Gtk::Builder> const& builder,
|
||||
Glib::RefPtr<Session> const& core,
|
||||
std::unique_ptr<tr_ctor, void (*)(tr_ctor*)> ctor);
|
||||
|
||||
TR_DISABLE_COPY_MOVE(Impl)
|
||||
|
||||
|
@ -43,17 +77,18 @@ private:
|
|||
|
||||
private:
|
||||
OptionsDialog& dialog_;
|
||||
|
||||
Glib::RefPtr<Session> const core_;
|
||||
std::unique_ptr<tr_ctor, void (*)(tr_ctor*)> ctor_;
|
||||
|
||||
std::string filename_;
|
||||
std::string downloadDir_;
|
||||
tr_torrent* tor_ = nullptr;
|
||||
|
||||
FileList* file_list_ = nullptr;
|
||||
Gtk::CheckButton* run_check_ = nullptr;
|
||||
Gtk::CheckButton* trash_check_ = nullptr;
|
||||
Gtk::ComboBox* priority_combo_ = nullptr;
|
||||
FreeSpaceLabel* freespace_label_ = nullptr;
|
||||
std::string filename_;
|
||||
std::string downloadDir_;
|
||||
tr_torrent* tor_ = nullptr;
|
||||
std::unique_ptr<tr_ctor, void (*)(tr_ctor*)> ctor_;
|
||||
};
|
||||
|
||||
void OptionsDialog::Impl::removeOldTorrent()
|
||||
|
@ -193,85 +228,57 @@ void addTorrentFilters(Gtk::FileChooser* chooser)
|
|||
*****
|
||||
****/
|
||||
|
||||
OptionsDialog::OptionsDialog(
|
||||
BaseObjectType* cast_item,
|
||||
Glib::RefPtr<Gtk::Builder> const& builder,
|
||||
Gtk::Window& parent,
|
||||
Glib::RefPtr<Session> const& core,
|
||||
std::unique_ptr<tr_ctor, void (*)(tr_ctor*)> ctor)
|
||||
: Gtk::Dialog(cast_item)
|
||||
, impl_(std::make_unique<Impl>(*this, builder, core, std::move(ctor)))
|
||||
{
|
||||
set_transient_for(parent);
|
||||
}
|
||||
|
||||
OptionsDialog::~OptionsDialog() = default;
|
||||
|
||||
std::unique_ptr<OptionsDialog> OptionsDialog::create(
|
||||
Gtk::Window& parent,
|
||||
Glib::RefPtr<Session> const& core,
|
||||
std::unique_ptr<tr_ctor, void (*)(tr_ctor*)> ctor)
|
||||
{
|
||||
return std::unique_ptr<OptionsDialog>(new OptionsDialog(parent, core, std::move(ctor)));
|
||||
auto const builder = Gtk::Builder::create_from_resource(gtr_get_full_resource_path("OptionsDialog.ui"));
|
||||
return std::unique_ptr<OptionsDialog>(
|
||||
gtr_get_widget_derived<OptionsDialog>(builder, "OptionsDialog", parent, core, std::move(ctor)));
|
||||
}
|
||||
|
||||
OptionsDialog::OptionsDialog(
|
||||
Gtk::Window& parent,
|
||||
Glib::RefPtr<Session> const& core,
|
||||
std::unique_ptr<tr_ctor, void (*)(tr_ctor*)> ctor)
|
||||
: Gtk::Dialog(_("Torrent Options"), parent, true /* modal */)
|
||||
, impl_(std::make_unique<Impl>(*this, core, std::move(ctor)))
|
||||
{
|
||||
}
|
||||
|
||||
OptionsDialog::~OptionsDialog() = default;
|
||||
|
||||
OptionsDialog::Impl::Impl(
|
||||
OptionsDialog& dialog,
|
||||
Glib::RefPtr<Gtk::Builder> const& builder,
|
||||
Glib::RefPtr<Session> const& core,
|
||||
std::unique_ptr<tr_ctor, void (*)(tr_ctor*)> ctor)
|
||||
: dialog_(dialog)
|
||||
, core_(core)
|
||||
, ctor_(std::move(ctor))
|
||||
, filename_(get_source_file(*ctor_))
|
||||
, downloadDir_(get_download_dir(*ctor_))
|
||||
, file_list_(gtr_get_widget_derived<FileList>(builder, "files_view_scroll", "files_view", core_, 0))
|
||||
, run_check_(gtr_get_widget<Gtk::CheckButton>(builder, "start_check"))
|
||||
, trash_check_(gtr_get_widget<Gtk::CheckButton>(builder, "trash_check"))
|
||||
, priority_combo_(gtr_get_widget<Gtk::ComboBox>(builder, "priority_combo"))
|
||||
, freespace_label_(gtr_get_widget_derived<FreeSpaceLabel>(builder, "free_space_label", core_, downloadDir_))
|
||||
{
|
||||
int row = 0;
|
||||
|
||||
/* make the dialog */
|
||||
dialog_.add_button(_("_Cancel"), Gtk::RESPONSE_CANCEL);
|
||||
dialog_.add_button(_("_Open"), Gtk::RESPONSE_ACCEPT);
|
||||
dialog_.set_default_response(Gtk::RESPONSE_ACCEPT);
|
||||
|
||||
char const* str = nullptr;
|
||||
if (!tr_ctorGetDownloadDir(ctor_.get(), TR_FORCE, &str))
|
||||
{
|
||||
g_assert_not_reached();
|
||||
}
|
||||
|
||||
g_assert(str != nullptr);
|
||||
|
||||
filename_ = tr_ctorGetSourceFile(ctor_.get()) != nullptr ? tr_ctorGetSourceFile(ctor_.get()) : "";
|
||||
downloadDir_ = str;
|
||||
file_list_ = Gtk::make_managed<FileList>(core_, 0);
|
||||
trash_check_ = Gtk::make_managed<Gtk::CheckButton>(_("Mo_ve torrent file to the trash"), true);
|
||||
run_check_ = Gtk::make_managed<Gtk::CheckButton>(_("_Start when added"), true);
|
||||
|
||||
priority_combo_ = gtr_priority_combo_new();
|
||||
gtr_priority_combo_set_value(*priority_combo_, TR_PRI_NORMAL);
|
||||
|
||||
dialog.signal_response().connect(sigc::mem_fun(*this, &Impl::addResponseCB));
|
||||
|
||||
auto* grid = Gtk::make_managed<Gtk::Grid>();
|
||||
grid->set_border_width(GUI_PAD_BIG);
|
||||
grid->set_row_spacing(GUI_PAD);
|
||||
grid->set_column_spacing(GUI_PAD_BIG);
|
||||
gtr_priority_combo_init(*priority_combo_);
|
||||
gtr_priority_combo_set_value(*priority_combo_, TR_PRI_NORMAL);
|
||||
|
||||
/* "torrent file" row */
|
||||
auto* source_label = Gtk::make_managed<Gtk::Label>(_("_Torrent file:"), true);
|
||||
source_label->set_halign(Gtk::ALIGN_START);
|
||||
source_label->set_halign(Gtk::ALIGN_CENTER);
|
||||
grid->attach(*source_label, 0, row, 1, 1);
|
||||
auto* source_chooser = Gtk::make_managed<Gtk::FileChooserButton>(_("Select Source File"), Gtk::FILE_CHOOSER_ACTION_OPEN);
|
||||
source_chooser->set_hexpand(true);
|
||||
grid->attach_next_to(*source_chooser, *source_label, Gtk::POS_RIGHT);
|
||||
source_label->set_mnemonic_widget(*source_chooser);
|
||||
auto* source_chooser = gtr_get_widget<Gtk::FileChooserButton>(builder, "source_button");
|
||||
addTorrentFilters(source_chooser);
|
||||
source_chooser->signal_selection_changed().connect([this, source_chooser]() { sourceChanged(source_chooser); });
|
||||
|
||||
/* "destination folder" row */
|
||||
row++;
|
||||
auto* destination_label = Gtk::make_managed<Gtk::Label>(_("_Destination folder:"), true);
|
||||
destination_label->set_halign(Gtk::ALIGN_START);
|
||||
destination_label->set_valign(Gtk::ALIGN_CENTER);
|
||||
grid->attach(*destination_label, 0, row, 1, 1);
|
||||
auto* destination_chooser = Gtk::make_managed<Gtk::FileChooserButton>(
|
||||
_("Select Destination Folder"),
|
||||
Gtk::FILE_CHOOSER_ACTION_SELECT_FOLDER);
|
||||
auto* destination_chooser = gtr_get_widget<Gtk::FileChooserButton>(builder, "destination_button");
|
||||
|
||||
if (!destination_chooser->set_current_folder(downloadDir_))
|
||||
{
|
||||
|
@ -284,36 +291,9 @@ OptionsDialog::Impl::Impl(
|
|||
destination_chooser->add_shortcut_folder(folder);
|
||||
}
|
||||
|
||||
grid->attach_next_to(*destination_chooser, *destination_label, Gtk::POS_RIGHT);
|
||||
destination_label->set_mnemonic_widget(*destination_chooser);
|
||||
destination_chooser->signal_selection_changed().connect([this, destination_chooser]()
|
||||
{ downloadDirChanged(destination_chooser); });
|
||||
|
||||
row++;
|
||||
freespace_label_ = Gtk::make_managed<FreeSpaceLabel>(core_, downloadDir_);
|
||||
freespace_label_->set_margin_bottom(GUI_PAD_BIG);
|
||||
freespace_label_->set_halign(Gtk::ALIGN_END);
|
||||
freespace_label_->set_valign(Gtk::ALIGN_CENTER);
|
||||
grid->attach(*freespace_label_, 0, row, 2, 1);
|
||||
|
||||
/* file list row */
|
||||
row++;
|
||||
file_list_->set_vexpand(true);
|
||||
file_list_->set_size_request(466U, 300U);
|
||||
grid->attach(*file_list_, 0, row, 2, 1);
|
||||
|
||||
/* torrent priority row */
|
||||
row++;
|
||||
auto* priority_label = Gtk::make_managed<Gtk::Label>(_("Torrent _priority:"), true);
|
||||
priority_label->set_halign(Gtk::ALIGN_START);
|
||||
priority_label->set_valign(Gtk::ALIGN_CENTER);
|
||||
grid->attach(*priority_label, 0, row, 1, 1);
|
||||
priority_label->set_mnemonic_widget(*priority_combo_);
|
||||
grid->attach_next_to(*priority_combo_, *priority_label, Gtk::POS_RIGHT);
|
||||
|
||||
/* torrent priority row */
|
||||
row++;
|
||||
|
||||
bool flag;
|
||||
if (!tr_ctorGetPaused(ctor_.get(), TR_FORCE, &flag))
|
||||
{
|
||||
|
@ -321,10 +301,6 @@ OptionsDialog::Impl::Impl(
|
|||
}
|
||||
|
||||
run_check_->set_active(!flag);
|
||||
grid->attach(*run_check_, 0, row, 2, 1);
|
||||
|
||||
/* "trash torrent file" row */
|
||||
row++;
|
||||
|
||||
if (!tr_ctorGetDeleteSource(ctor_.get(), &flag))
|
||||
{
|
||||
|
@ -332,7 +308,6 @@ OptionsDialog::Impl::Impl(
|
|||
}
|
||||
|
||||
trash_check_->set_active(flag);
|
||||
grid->attach(*trash_check_, 0, row, 2, 1);
|
||||
|
||||
/* trigger sourceChanged, either directly or indirectly,
|
||||
* so that it creates the tor/gtor objects */
|
||||
|
@ -345,7 +320,6 @@ OptionsDialog::Impl::Impl(
|
|||
sourceChanged(source_chooser);
|
||||
}
|
||||
|
||||
gtr_dialog_set_content(dialog_, *grid);
|
||||
dialog_.get_widget_for_response(Gtk::RESPONSE_ACCEPT)->grab_focus();
|
||||
}
|
||||
|
||||
|
@ -406,7 +380,7 @@ TorrentFileChooserDialog::TorrentFileChooserDialog(Gtk::Window& parent, Glib::Re
|
|||
****
|
||||
***/
|
||||
|
||||
void TorrentUrlChooserDialog::onOpenURLResponse(int response, Glib::RefPtr<Session> const& core)
|
||||
void TorrentUrlChooserDialog::onOpenURLResponse(int response, Gtk::Entry const& entry, Glib::RefPtr<Session> const& core)
|
||||
{
|
||||
|
||||
if (response == Gtk::RESPONSE_CANCEL)
|
||||
|
@ -415,8 +389,7 @@ void TorrentUrlChooserDialog::onOpenURLResponse(int response, Glib::RefPtr<Sessi
|
|||
}
|
||||
else if (response == Gtk::RESPONSE_ACCEPT)
|
||||
{
|
||||
auto const* const e = static_cast<Gtk::Entry*>(get_data("url-entry"));
|
||||
auto const url = gtr_str_strip(e->get_text());
|
||||
auto const url = gtr_str_strip(entry.get_text());
|
||||
|
||||
if (url.empty())
|
||||
{
|
||||
|
@ -436,28 +409,24 @@ void TorrentUrlChooserDialog::onOpenURLResponse(int response, Glib::RefPtr<Sessi
|
|||
|
||||
std::unique_ptr<TorrentUrlChooserDialog> TorrentUrlChooserDialog::create(Gtk::Window& parent, Glib::RefPtr<Session> const& core)
|
||||
{
|
||||
return std::unique_ptr<TorrentUrlChooserDialog>(new TorrentUrlChooserDialog(parent, core));
|
||||
auto const builder = Gtk::Builder::create_from_resource(gtr_get_full_resource_path("TorrentUrlChooserDialog.ui"));
|
||||
return std::unique_ptr<TorrentUrlChooserDialog>(
|
||||
gtr_get_widget_derived<TorrentUrlChooserDialog>(builder, "TorrentUrlChooserDialog", parent, core));
|
||||
}
|
||||
|
||||
TorrentUrlChooserDialog::TorrentUrlChooserDialog(Gtk::Window& parent, Glib::RefPtr<Session> const& core)
|
||||
: Gtk::Dialog(_("Open URL"), parent, true /* modal */)
|
||||
TorrentUrlChooserDialog::TorrentUrlChooserDialog(
|
||||
BaseObjectType* cast_item,
|
||||
Glib::RefPtr<Gtk::Builder> const& builder,
|
||||
Gtk::Window& parent,
|
||||
Glib::RefPtr<Session> const& core)
|
||||
: Gtk::Dialog(cast_item)
|
||||
{
|
||||
guint row;
|
||||
set_transient_for(parent);
|
||||
|
||||
add_button(_("_Cancel"), Gtk::RESPONSE_CANCEL);
|
||||
add_button(_("_Open"), Gtk::RESPONSE_ACCEPT);
|
||||
signal_response().connect([this, core](int response) { onOpenURLResponse(response, core); });
|
||||
|
||||
row = 0;
|
||||
auto* t = Gtk::make_managed<HigWorkarea>();
|
||||
t->add_section_title(row, _("Open torrent from URL"));
|
||||
auto* e = Gtk::make_managed<Gtk::Entry>();
|
||||
e->set_size_request(400, -1);
|
||||
auto* const e = gtr_get_widget<Gtk::Entry>(builder, "url_entry");
|
||||
gtr_paste_clipboard_url_into_entry(*e);
|
||||
set_data("url-entry", e);
|
||||
t->add_row(row, _("_URL"), *e);
|
||||
|
||||
gtr_dialog_set_content(*this, *t);
|
||||
signal_response().connect([this, e, core](int response) { onOpenURLResponse(response, *e, core); });
|
||||
|
||||
if (e->get_text_length() == 0)
|
||||
{
|
||||
|
|
|
@ -17,15 +17,18 @@ typedef struct tr_ctor tr_ctor;
|
|||
class TorrentUrlChooserDialog : public Gtk::Dialog
|
||||
{
|
||||
public:
|
||||
TorrentUrlChooserDialog(
|
||||
BaseObjectType* cast_item,
|
||||
Glib::RefPtr<Gtk::Builder> const& builder,
|
||||
Gtk::Window& parent,
|
||||
Glib::RefPtr<Session> const& core);
|
||||
|
||||
TR_DISABLE_COPY_MOVE(TorrentUrlChooserDialog)
|
||||
|
||||
static std::unique_ptr<TorrentUrlChooserDialog> create(Gtk::Window& parent, Glib::RefPtr<Session> const& core);
|
||||
|
||||
protected:
|
||||
TorrentUrlChooserDialog(Gtk::Window& parent, Glib::RefPtr<Session> const& core);
|
||||
|
||||
private:
|
||||
void onOpenURLResponse(int response, Glib::RefPtr<Session> const& core);
|
||||
void onOpenURLResponse(int response, Gtk::Entry const& entry, Glib::RefPtr<Session> const& core);
|
||||
};
|
||||
|
||||
class TorrentFileChooserDialog : public Gtk::FileChooserDialog
|
||||
|
@ -45,6 +48,12 @@ private:
|
|||
class OptionsDialog : public Gtk::Dialog
|
||||
{
|
||||
public:
|
||||
OptionsDialog(
|
||||
BaseObjectType* cast_item,
|
||||
Glib::RefPtr<Gtk::Builder> const& builder,
|
||||
Gtk::Window& parent,
|
||||
Glib::RefPtr<Session> const& core,
|
||||
std::unique_ptr<tr_ctor, void (*)(tr_ctor*)> ctor);
|
||||
~OptionsDialog() override;
|
||||
|
||||
TR_DISABLE_COPY_MOVE(OptionsDialog)
|
||||
|
@ -54,9 +63,6 @@ public:
|
|||
Glib::RefPtr<Session> const& core,
|
||||
std::unique_ptr<tr_ctor, void (*)(tr_ctor*)> ctor);
|
||||
|
||||
protected:
|
||||
OptionsDialog(Gtk::Window& parent, Glib::RefPtr<Session> const& core, std::unique_ptr<tr_ctor, void (*)(tr_ctor*)> ctor);
|
||||
|
||||
private:
|
||||
class Impl;
|
||||
std::unique_ptr<Impl> const impl_;
|
||||
|
|
|
@ -0,0 +1,252 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Generated with glade 3.38.2 -->
|
||||
<interface domain="transmission-gtk">
|
||||
<requires lib="gtk+" version="3.24"/>
|
||||
<object class="GtkDialog" id="OptionsDialog">
|
||||
<property name="can-focus">False</property>
|
||||
<property name="border-width">6</property>
|
||||
<property name="title" translatable="yes">Torrent Options</property>
|
||||
<property name="type-hint">dialog</property>
|
||||
<child internal-child="vbox">
|
||||
<object class="GtkBox" id="dialog_layout">
|
||||
<property name="can-focus">False</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">6</property>
|
||||
<child internal-child="action_area">
|
||||
<object class="GtkButtonBox" id="dialog_buttons">
|
||||
<property name="can-focus">False</property>
|
||||
<property name="layout-style">end</property>
|
||||
<child>
|
||||
<object class="GtkButton" id="cancel_button">
|
||||
<property name="label" translatable="yes">_Cancel</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="can-default">True</property>
|
||||
<property name="receives-default">True</property>
|
||||
<property name="use-underline">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="open_button">
|
||||
<property name="label" translatable="yes">_Open</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="can-default">True</property>
|
||||
<property name="receives-default">True</property>
|
||||
<property name="use-underline">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<!-- n-columns=2 n-rows=8 -->
|
||||
<object class="GtkGrid" id="dialog_content_layout">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="row-spacing">6</property>
|
||||
<property name="column-spacing">12</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="source_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="label" translatable="yes">_Torrent file:</property>
|
||||
<property name="use-underline">True</property>
|
||||
<property name="mnemonic-widget">source_button</property>
|
||||
<property name="xalign">0</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkFileChooserButton" id="source_button">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="title" translatable="yes">Select Source File</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">1</property>
|
||||
<property name="top-attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="destination_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="label" translatable="yes">_Destination folder:</property>
|
||||
<property name="use-underline">True</property>
|
||||
<property name="mnemonic-widget">destination_button</property>
|
||||
<property name="xalign">0</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkFileChooserButton" id="destination_button">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="action">select-folder</property>
|
||||
<property name="title" translatable="yes">Select Destination Folder</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">1</property>
|
||||
<property name="top-attach">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow" id="files_view_scroll">
|
||||
<property name="width-request">466</property>
|
||||
<property name="height-request">300</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="shadow-type">in</property>
|
||||
<child>
|
||||
<object class="GtkTreeView" id="files_view">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="vexpand">True</property>
|
||||
<child internal-child="selection">
|
||||
<object class="GtkTreeSelection" id="files_view_selection"/>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">4</property>
|
||||
<property name="width">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="priority_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="label" translatable="yes">Torrent _priority:</property>
|
||||
<property name="use-underline">True</property>
|
||||
<property name="mnemonic-widget">priority_combo</property>
|
||||
<property name="xalign">0</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">5</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkComboBox" id="priority_combo">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="hexpand">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">1</property>
|
||||
<property name="top-attach">5</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkCheckButton" id="start_check">
|
||||
<property name="label" translatable="yes">_Start when added</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="receives-default">False</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="use-underline">True</property>
|
||||
<property name="draw-indicator">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">6</property>
|
||||
<property name="width">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkCheckButton" id="trash_check">
|
||||
<property name="label" translatable="yes">Mo_ve torrent file to the trash</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="receives-default">False</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="use-underline">True</property>
|
||||
<property name="draw-indicator">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">7</property>
|
||||
<property name="width">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="free_space_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="label">...</property>
|
||||
<property name="xalign">0</property>
|
||||
<attributes>
|
||||
<attribute name="style" value="italic"/>
|
||||
</attributes>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">1</property>
|
||||
<property name="top-attach">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkFixed">
|
||||
<property name="width-request">0</property>
|
||||
<property name="height-request">0</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkFixed">
|
||||
<property name="height-request">6</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">3</property>
|
||||
<property name="width">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<action-widgets>
|
||||
<action-widget response="-6">cancel_button</action-widget>
|
||||
<action-widget response="-3">open_button</action-widget>
|
||||
</action-widgets>
|
||||
</object>
|
||||
</interface>
|
1249
gtk/PrefsDialog.cc
1249
gtk/PrefsDialog.cc
File diff suppressed because it is too large
Load Diff
|
@ -16,15 +16,17 @@ class Session;
|
|||
class PrefsDialog : public Gtk::Dialog
|
||||
{
|
||||
public:
|
||||
PrefsDialog(
|
||||
BaseObjectType* cast_item,
|
||||
Glib::RefPtr<Gtk::Builder> const& builder,
|
||||
Gtk::Window& parent,
|
||||
Glib::RefPtr<Session> const& core);
|
||||
~PrefsDialog() override;
|
||||
|
||||
TR_DISABLE_COPY_MOVE(PrefsDialog)
|
||||
|
||||
static std::unique_ptr<PrefsDialog> create(Gtk::Window& parent, Glib::RefPtr<Session> const& core);
|
||||
|
||||
protected:
|
||||
PrefsDialog(Gtk::Window& parent, Glib::RefPtr<Session> const& core);
|
||||
|
||||
private:
|
||||
class Impl;
|
||||
std::unique_ptr<Impl> const impl_;
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -13,7 +13,6 @@
|
|||
|
||||
#include <libtransmission/transmission.h>
|
||||
|
||||
#include "HigWorkarea.h"
|
||||
#include "Prefs.h" /* gtr_pref_string_get */
|
||||
#include "RelocateDialog.h"
|
||||
#include "Session.h"
|
||||
|
@ -29,7 +28,11 @@ std::string targetLocation;
|
|||
class RelocateDialog::Impl
|
||||
{
|
||||
public:
|
||||
Impl(RelocateDialog& dialog, Glib::RefPtr<Session> const& core, std::vector<tr_torrent_id_t> const& torrent_ids);
|
||||
Impl(
|
||||
RelocateDialog& dialog,
|
||||
Glib::RefPtr<Gtk::Builder> const& builder,
|
||||
Glib::RefPtr<Session> const& core,
|
||||
std::vector<tr_torrent_id_t> const& torrent_ids);
|
||||
~Impl();
|
||||
|
||||
TR_DISABLE_COPY_MOVE(Impl)
|
||||
|
@ -140,46 +143,44 @@ void RelocateDialog::Impl::onResponse(int response)
|
|||
}
|
||||
}
|
||||
|
||||
RelocateDialog::RelocateDialog(
|
||||
BaseObjectType* cast_item,
|
||||
Glib::RefPtr<Gtk::Builder> const& builder,
|
||||
Gtk::Window& parent,
|
||||
Glib::RefPtr<Session> const& core,
|
||||
std::vector<int> const& torrent_ids)
|
||||
: Gtk::Dialog(cast_item)
|
||||
, impl_(std::make_unique<Impl>(*this, builder, core, torrent_ids))
|
||||
{
|
||||
set_transient_for(parent);
|
||||
}
|
||||
|
||||
RelocateDialog::~RelocateDialog() = default;
|
||||
|
||||
std::unique_ptr<RelocateDialog> RelocateDialog::create(
|
||||
Gtk::Window& parent,
|
||||
Glib::RefPtr<Session> const& core,
|
||||
std::vector<tr_torrent_id_t> const& torrent_ids)
|
||||
{
|
||||
return std::unique_ptr<RelocateDialog>(new RelocateDialog(parent, core, torrent_ids));
|
||||
auto const builder = Gtk::Builder::create_from_resource(gtr_get_full_resource_path("RelocateDialog.ui"));
|
||||
return std::unique_ptr<RelocateDialog>(
|
||||
gtr_get_widget_derived<RelocateDialog>(builder, "RelocateDialog", parent, core, torrent_ids));
|
||||
}
|
||||
|
||||
RelocateDialog::RelocateDialog(
|
||||
Gtk::Window& parent,
|
||||
Glib::RefPtr<Session> const& core,
|
||||
std::vector<tr_torrent_id_t> const& torrent_ids)
|
||||
: Gtk::Dialog(_("Set Torrent Location"), parent, true)
|
||||
, impl_(std::make_unique<Impl>(*this, core, torrent_ids))
|
||||
{
|
||||
}
|
||||
|
||||
RelocateDialog::~RelocateDialog() = default;
|
||||
|
||||
RelocateDialog::Impl::Impl(
|
||||
RelocateDialog& dialog,
|
||||
Glib::RefPtr<Gtk::Builder> const& builder,
|
||||
Glib::RefPtr<Session> const& core,
|
||||
std::vector<tr_torrent_id_t> const& torrent_ids)
|
||||
: dialog_(dialog)
|
||||
, core_(core)
|
||||
, torrent_ids_(torrent_ids)
|
||||
, chooser_(gtr_get_widget<Gtk::FileChooserButton>(builder, "new_location_button"))
|
||||
, move_tb_(gtr_get_widget<Gtk::RadioButton>(builder, "move_data_radio"))
|
||||
{
|
||||
guint row;
|
||||
|
||||
dialog_.add_button(_("_Cancel"), Gtk::RESPONSE_CANCEL);
|
||||
dialog_.add_button(_("_Apply"), Gtk::RESPONSE_APPLY);
|
||||
dialog_.set_default_response(Gtk::RESPONSE_CANCEL);
|
||||
dialog_.signal_response().connect(sigc::mem_fun(*this, &Impl::onResponse));
|
||||
|
||||
row = 0;
|
||||
auto* t = Gtk::make_managed<HigWorkarea>();
|
||||
t->add_section_title(row, _("Location"));
|
||||
|
||||
chooser_ = Gtk::make_managed<Gtk::FileChooserButton>(_("Set Torrent Location"), Gtk::FILE_CHOOSER_ACTION_SELECT_FOLDER);
|
||||
|
||||
auto recent_dirs = gtr_get_recent_dirs("relocate");
|
||||
if (recent_dirs.empty())
|
||||
{
|
||||
|
@ -199,15 +200,4 @@ RelocateDialog::Impl::Impl(
|
|||
chooser_->add_shortcut_folder(folder);
|
||||
}
|
||||
}
|
||||
|
||||
t->add_row(row, _("Torrent _location:"), *chooser_);
|
||||
|
||||
Gtk::RadioButton::Group group;
|
||||
|
||||
move_tb_ = Gtk::make_managed<Gtk::RadioButton>(group, _("_Move from the current folder"), true);
|
||||
t->add_wide_control(row, *move_tb_);
|
||||
|
||||
t->add_wide_control(row, *Gtk::make_managed<Gtk::RadioButton>(group, _("Local data is _already there"), true));
|
||||
|
||||
gtr_dialog_set_content(dialog_, *t);
|
||||
}
|
||||
|
|
|
@ -17,6 +17,12 @@ class Session;
|
|||
class RelocateDialog : public Gtk::Dialog
|
||||
{
|
||||
public:
|
||||
RelocateDialog(
|
||||
BaseObjectType* cast_item,
|
||||
Glib::RefPtr<Gtk::Builder> const& builder,
|
||||
Gtk::Window& parent,
|
||||
Glib::RefPtr<Session> const& core,
|
||||
std::vector<tr_torrent_id_t> const& torrent_ids);
|
||||
~RelocateDialog() override;
|
||||
|
||||
TR_DISABLE_COPY_MOVE(RelocateDialog)
|
||||
|
@ -26,9 +32,6 @@ public:
|
|||
Glib::RefPtr<Session> const& core,
|
||||
std::vector<tr_torrent_id_t> const& torrent_ids);
|
||||
|
||||
protected:
|
||||
RelocateDialog(Gtk::Window& parent, Glib::RefPtr<Session> const& core, std::vector<tr_torrent_id_t> const& torrent_ids);
|
||||
|
||||
private:
|
||||
class Impl;
|
||||
std::unique_ptr<Impl> const impl_;
|
||||
|
|
|
@ -0,0 +1,171 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Generated with glade 3.38.2 -->
|
||||
<interface domain="transmission-gtk">
|
||||
<requires lib="gtk+" version="3.24"/>
|
||||
<object class="GtkDialog" id="RelocateDialog">
|
||||
<property name="can-focus">False</property>
|
||||
<property name="border-width">6</property>
|
||||
<property name="title" translatable="yes">Set Torrent Location</property>
|
||||
<property name="type-hint">dialog</property>
|
||||
<child internal-child="vbox">
|
||||
<object class="GtkBox" id="dialog_layout">
|
||||
<property name="can-focus">False</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">6</property>
|
||||
<child internal-child="action_area">
|
||||
<object class="GtkButtonBox" id="dialog_buttons">
|
||||
<property name="can-focus">False</property>
|
||||
<property name="layout-style">end</property>
|
||||
<child>
|
||||
<object class="GtkButton" id="cancel_button">
|
||||
<property name="label" translatable="yes">_Cancel</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="can-default">True</property>
|
||||
<property name="receives-default">True</property>
|
||||
<property name="use-underline">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="apply_button">
|
||||
<property name="label" translatable="yes">_Apply</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="can-default">True</property>
|
||||
<property name="receives-default">True</property>
|
||||
<property name="use-underline">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox" id="dialog_content_layout">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">6</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="set_location_section_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="label" translatable="yes">Location</property>
|
||||
<property name="xalign">0</property>
|
||||
<attributes>
|
||||
<attribute name="weight" value="bold"/>
|
||||
</attributes>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<!-- n-columns=2 n-rows=3 -->
|
||||
<object class="GtkGrid" id="set_location_section_layout">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="margin-start">18</property>
|
||||
<property name="row-spacing">6</property>
|
||||
<property name="column-spacing">12</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="new_location_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="halign">start</property>
|
||||
<property name="label" translatable="yes">Torrent _location:</property>
|
||||
<property name="use-underline">True</property>
|
||||
<property name="mnemonic-widget">new_location_button</property>
|
||||
<property name="xalign">0</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkFileChooserButton" id="new_location_button">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="action">select-folder</property>
|
||||
<property name="title" translatable="yes"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">1</property>
|
||||
<property name="top-attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkRadioButton" id="move_data_radio">
|
||||
<property name="label" translatable="yes">_Move from the current folder</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="receives-default">False</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="use-underline">True</property>
|
||||
<property name="active">True</property>
|
||||
<property name="draw-indicator">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">1</property>
|
||||
<property name="width">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkRadioButton" id="find_data_radio">
|
||||
<property name="label" translatable="yes">Local data is _already there</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="receives-default">False</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="use-underline">True</property>
|
||||
<property name="active">True</property>
|
||||
<property name="draw-indicator">True</property>
|
||||
<property name="group">move_data_radio</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">2</property>
|
||||
<property name="width">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<action-widgets>
|
||||
<action-widget response="-6">cancel_button</action-widget>
|
||||
<action-widget response="-10">apply_button</action-widget>
|
||||
</action-widgets>
|
||||
</object>
|
||||
</interface>
|
|
@ -10,7 +10,6 @@
|
|||
|
||||
#include <fmt/core.h>
|
||||
|
||||
#include "HigWorkarea.h"
|
||||
#include "PrefsDialog.h"
|
||||
#include "Session.h"
|
||||
#include "StatsDialog.h"
|
||||
|
@ -21,7 +20,7 @@ static auto constexpr TR_RESPONSE_RESET = int{ 1 };
|
|||
class StatsDialog::Impl
|
||||
{
|
||||
public:
|
||||
Impl(StatsDialog& dialog, Glib::RefPtr<Session> const& core);
|
||||
Impl(StatsDialog& dialog, Glib::RefPtr<Gtk::Builder> const& builder, Glib::RefPtr<Session> const& core);
|
||||
~Impl();
|
||||
|
||||
TR_DISABLE_COPY_MOVE(Impl)
|
||||
|
@ -116,70 +115,42 @@ void StatsDialog::Impl::dialogResponse(int response)
|
|||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<StatsDialog> StatsDialog::create(Gtk::Window& parent, Glib::RefPtr<Session> const& core)
|
||||
{
|
||||
return std::unique_ptr<StatsDialog>(new StatsDialog(parent, core));
|
||||
}
|
||||
|
||||
StatsDialog::StatsDialog(Gtk::Window& parent, Glib::RefPtr<Session> const& core)
|
||||
: Gtk::Dialog(_("Statistics"), parent)
|
||||
, impl_(std::make_unique<Impl>(*this, core))
|
||||
StatsDialog::StatsDialog(
|
||||
BaseObjectType* cast_item,
|
||||
Glib::RefPtr<Gtk::Builder> const& builder,
|
||||
Gtk::Window& parent,
|
||||
Glib::RefPtr<Session> const& core)
|
||||
: Gtk::Dialog(cast_item)
|
||||
, impl_(std::make_unique<Impl>(*this, builder, core))
|
||||
{
|
||||
set_transient_for(parent);
|
||||
}
|
||||
|
||||
StatsDialog::~StatsDialog() = default;
|
||||
|
||||
StatsDialog::Impl::Impl(StatsDialog& dialog, Glib::RefPtr<Session> const& core)
|
||||
std::unique_ptr<StatsDialog> StatsDialog::create(Gtk::Window& parent, Glib::RefPtr<Session> const& core)
|
||||
{
|
||||
auto const builder = Gtk::Builder::create_from_resource(gtr_get_full_resource_path("StatsDialog.ui"));
|
||||
return std::unique_ptr<StatsDialog>(gtr_get_widget_derived<StatsDialog>(builder, "StatsDialog", parent, core));
|
||||
}
|
||||
|
||||
StatsDialog::Impl::Impl(StatsDialog& dialog, Glib::RefPtr<Gtk::Builder> const& builder, Glib::RefPtr<Session> const& core)
|
||||
: dialog_(dialog)
|
||||
, core_(core)
|
||||
, one_up_lb_(gtr_get_widget<Gtk::Label>(builder, "current_uploaded_value_label"))
|
||||
, one_down_lb_(gtr_get_widget<Gtk::Label>(builder, "current_downloaded_value_label"))
|
||||
, one_ratio_lb_(gtr_get_widget<Gtk::Label>(builder, "current_ratio_value_label"))
|
||||
, one_time_lb_(gtr_get_widget<Gtk::Label>(builder, "current_duration_value_label"))
|
||||
, all_up_lb_(gtr_get_widget<Gtk::Label>(builder, "total_uploaded_value_label"))
|
||||
, all_down_lb_(gtr_get_widget<Gtk::Label>(builder, "total_downloaded_value_label"))
|
||||
, all_ratio_lb_(gtr_get_widget<Gtk::Label>(builder, "total_ratio_value_label"))
|
||||
, all_time_lb_(gtr_get_widget<Gtk::Label>(builder, "total_duration_value_label"))
|
||||
, all_sessions_lb_(gtr_get_widget<Gtk::Label>(builder, "start_count_label"))
|
||||
{
|
||||
guint row = 0;
|
||||
|
||||
dialog_.add_button(_("_Reset"), TR_RESPONSE_RESET);
|
||||
dialog_.add_button(_("_Close"), Gtk::RESPONSE_CLOSE);
|
||||
dialog_.set_default_response(Gtk::RESPONSE_CLOSE);
|
||||
|
||||
auto* t = Gtk::make_managed<HigWorkarea>();
|
||||
t->add_section_title(row, _("Current Session"));
|
||||
|
||||
one_up_lb_ = Gtk::make_managed<Gtk::Label>();
|
||||
one_up_lb_->set_single_line_mode(true);
|
||||
t->add_row(row, _("Uploaded:"), *one_up_lb_);
|
||||
one_down_lb_ = Gtk::make_managed<Gtk::Label>();
|
||||
one_down_lb_->set_single_line_mode(true);
|
||||
t->add_row(row, _("Downloaded:"), *one_down_lb_);
|
||||
one_ratio_lb_ = Gtk::make_managed<Gtk::Label>();
|
||||
one_ratio_lb_->set_single_line_mode(true);
|
||||
t->add_row(row, _("Ratio:"), *one_ratio_lb_);
|
||||
one_time_lb_ = Gtk::make_managed<Gtk::Label>();
|
||||
one_time_lb_->set_single_line_mode(true);
|
||||
t->add_row(row, _("Duration:"), *one_time_lb_);
|
||||
|
||||
t->add_section_divider(row);
|
||||
t->add_section_title(row, _("Total"));
|
||||
|
||||
all_sessions_lb_ = Gtk::make_managed<Gtk::Label>(startedTimesText(1));
|
||||
all_sessions_lb_->set_single_line_mode(true);
|
||||
t->add_label_w(row, *all_sessions_lb_);
|
||||
++row;
|
||||
|
||||
all_up_lb_ = Gtk::make_managed<Gtk::Label>();
|
||||
all_up_lb_->set_single_line_mode(true);
|
||||
t->add_row(row, _("Uploaded:"), *all_up_lb_);
|
||||
all_down_lb_ = Gtk::make_managed<Gtk::Label>();
|
||||
all_down_lb_->set_single_line_mode(true);
|
||||
t->add_row(row, _("Downloaded:"), *all_down_lb_);
|
||||
all_ratio_lb_ = Gtk::make_managed<Gtk::Label>();
|
||||
all_ratio_lb_->set_single_line_mode(true);
|
||||
t->add_row(row, _("Ratio:"), *all_ratio_lb_);
|
||||
all_time_lb_ = Gtk::make_managed<Gtk::Label>();
|
||||
all_time_lb_->set_single_line_mode(true);
|
||||
t->add_row(row, _("Duration:"), *all_time_lb_);
|
||||
|
||||
gtr_dialog_set_content(dialog_, *t);
|
||||
dialog_.signal_response().connect(sigc::mem_fun(*this, &Impl::dialogResponse));
|
||||
|
||||
updateStats();
|
||||
dialog_.signal_response().connect(sigc::mem_fun(*this, &Impl::dialogResponse));
|
||||
update_stats_tag_ = Glib::signal_timeout().connect_seconds(
|
||||
sigc::mem_fun(*this, &Impl::updateStats),
|
||||
SECONDARY_WINDOW_REFRESH_INTERVAL_SECONDS);
|
||||
|
|
|
@ -16,15 +16,17 @@ class Session;
|
|||
class StatsDialog : public Gtk::Dialog
|
||||
{
|
||||
public:
|
||||
StatsDialog(
|
||||
BaseObjectType* cast_item,
|
||||
Glib::RefPtr<Gtk::Builder> const& builder,
|
||||
Gtk::Window& parent,
|
||||
Glib::RefPtr<Session> const& core);
|
||||
~StatsDialog() override;
|
||||
|
||||
TR_DISABLE_COPY_MOVE(StatsDialog)
|
||||
|
||||
static std::unique_ptr<StatsDialog> create(Gtk::Window& parent, Glib::RefPtr<Session> const& core);
|
||||
|
||||
protected:
|
||||
StatsDialog(Gtk::Window& parent, Glib::RefPtr<Session> const& core);
|
||||
|
||||
private:
|
||||
class Impl;
|
||||
std::unique_ptr<Impl> const impl_;
|
||||
|
|
|
@ -0,0 +1,379 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Generated with glade 3.38.2 -->
|
||||
<interface domain="transmission-gtk">
|
||||
<requires lib="gtk+" version="3.24"/>
|
||||
<object class="GtkDialog" id="StatsDialog">
|
||||
<property name="can-focus">False</property>
|
||||
<property name="border-width">6</property>
|
||||
<property name="title" translatable="yes">Statistics</property>
|
||||
<property name="type-hint">dialog</property>
|
||||
<child internal-child="vbox">
|
||||
<object class="GtkBox" id="dialog_layout">
|
||||
<property name="can-focus">False</property>
|
||||
<property name="margin-top">1</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">6</property>
|
||||
<child internal-child="action_area">
|
||||
<object class="GtkButtonBox" id="dialog_buttons">
|
||||
<property name="can-focus">False</property>
|
||||
<property name="layout-style">end</property>
|
||||
<child>
|
||||
<object class="GtkButton" id="reset_button">
|
||||
<property name="label" translatable="yes">_Reset</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="can-default">True</property>
|
||||
<property name="receives-default">True</property>
|
||||
<property name="use-underline">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="close_button">
|
||||
<property name="label" translatable="yes">_Close</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="can-default">True</property>
|
||||
<property name="receives-default">True</property>
|
||||
<property name="use-underline">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox" id="dialog_content_layout">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">6</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="current_session_section_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="label" translatable="yes">Current Session</property>
|
||||
<property name="xalign">0</property>
|
||||
<attributes>
|
||||
<attribute name="weight" value="bold"/>
|
||||
</attributes>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<!-- n-columns=2 n-rows=4 -->
|
||||
<object class="GtkGrid" id="current_session_section_layout">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="margin-start">18</property>
|
||||
<property name="row-spacing">6</property>
|
||||
<property name="column-spacing">12</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="current_uploaded_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="label" translatable="yes">Uploaded:</property>
|
||||
<property name="xalign">0</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="current_uploaded_value_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="label">...</property>
|
||||
<property name="xalign">0</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">1</property>
|
||||
<property name="top-attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="current_downloaded_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="label" translatable="yes">Downloaded:</property>
|
||||
<property name="xalign">0</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="current_downloaded_value_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="label">...</property>
|
||||
<property name="xalign">0</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">1</property>
|
||||
<property name="top-attach">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="current_ratio_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="label" translatable="yes">Ratio:</property>
|
||||
<property name="xalign">0</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="current_ratio_value_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="label">...</property>
|
||||
<property name="xalign">0</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">1</property>
|
||||
<property name="top-attach">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="current_duration_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="label" translatable="yes">Duration:</property>
|
||||
<property name="xalign">0</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="current_duration_value_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="label">...</property>
|
||||
<property name="xalign">0</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">1</property>
|
||||
<property name="top-attach">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkFixed" id="total_section_spacer">
|
||||
<property name="height-request">6</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="total_section_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="label" translatable="yes">Total</property>
|
||||
<property name="xalign">0</property>
|
||||
<attributes>
|
||||
<attribute name="weight" value="bold"/>
|
||||
</attributes>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<!-- n-columns=2 n-rows=5 -->
|
||||
<object class="GtkGrid" id="total_section_layout">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="margin-start">18</property>
|
||||
<property name="row-spacing">6</property>
|
||||
<property name="column-spacing">12</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="start_count_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="label">...</property>
|
||||
<property name="xalign">0</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">0</property>
|
||||
<property name="width">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="total_uploaded_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="label" translatable="yes">Uploaded:</property>
|
||||
<property name="xalign">0</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="total_uploaded_value_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="label">...</property>
|
||||
<property name="xalign">0</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">1</property>
|
||||
<property name="top-attach">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="total_downloaded_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="label" translatable="yes">Downloaded:</property>
|
||||
<property name="xalign">0</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="total_downloaded_value_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="label">...</property>
|
||||
<property name="xalign">0</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">1</property>
|
||||
<property name="top-attach">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="total_ratio_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="label" translatable="yes">Ratio:</property>
|
||||
<property name="xalign">0</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="total_ratio_value_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="label">...</property>
|
||||
<property name="xalign">0</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">1</property>
|
||||
<property name="top-attach">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="total_duration_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="label" translatable="yes">Duration:</property>
|
||||
<property name="xalign">0</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">4</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="total_duration_value_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="label">...</property>
|
||||
<property name="xalign">0</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">1</property>
|
||||
<property name="top-attach">4</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">4</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<action-widgets>
|
||||
<action-widget response="1">reset_button</action-widget>
|
||||
<action-widget response="-7">close_button</action-widget>
|
||||
</action-widgets>
|
||||
</object>
|
||||
<object class="GtkSizeGroup" id="labels_width_group">
|
||||
<widgets>
|
||||
<widget name="current_uploaded_label"/>
|
||||
<widget name="current_downloaded_label"/>
|
||||
<widget name="current_ratio_label"/>
|
||||
<widget name="current_duration_label"/>
|
||||
<widget name="total_uploaded_label"/>
|
||||
<widget name="total_downloaded_label"/>
|
||||
<widget name="total_ratio_label"/>
|
||||
<widget name="total_duration_label"/>
|
||||
</widgets>
|
||||
</object>
|
||||
</interface>
|
|
@ -19,7 +19,7 @@
|
|||
#include <libtransmission/transmission.h>
|
||||
#include <libtransmission/utils.h> /* tr_truncd() */
|
||||
|
||||
#include "HigWorkarea.h"
|
||||
#include "HigWorkarea.h" // GUI_PAD, GUI_PAD_SMALL
|
||||
#include "IconCache.h"
|
||||
#include "TorrentCellRenderer.h"
|
||||
#include "Utils.h"
|
||||
|
|
|
@ -0,0 +1,130 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Generated with glade 3.38.2 -->
|
||||
<interface>
|
||||
<requires lib="gtk+" version="3.24"/>
|
||||
<object class="GtkDialog" id="TorrentUrlChooserDialog">
|
||||
<property name="can-focus">False</property>
|
||||
<property name="border-width">6</property>
|
||||
<property name="title" translatable="yes">Open URL</property>
|
||||
<property name="type-hint">dialog</property>
|
||||
<child internal-child="vbox">
|
||||
<object class="GtkBox" id="dialog_layout">
|
||||
<property name="can-focus">False</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">6</property>
|
||||
<child internal-child="action_area">
|
||||
<object class="GtkButtonBox" id="dialog_buttons">
|
||||
<property name="can-focus">False</property>
|
||||
<property name="layout-style">end</property>
|
||||
<child>
|
||||
<object class="GtkButton" id="cancel_button">
|
||||
<property name="label" translatable="yes">_Cancel</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="receives-default">True</property>
|
||||
<property name="use-underline">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="open_button">
|
||||
<property name="label" translatable="yes">_Open</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="receives-default">True</property>
|
||||
<property name="use-underline">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox" id="dialog_content_layout">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">6</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="url_section_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="label" translatable="yes">Open torrent from URL</property>
|
||||
<property name="xalign">0</property>
|
||||
<attributes>
|
||||
<attribute name="weight" value="bold"/>
|
||||
</attributes>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<!-- n-columns=2 n-rows=1 -->
|
||||
<object class="GtkGrid" id="url_section_layout">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="margin-start">18</property>
|
||||
<property name="row-spacing">6</property>
|
||||
<property name="column-spacing">12</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="url_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="label" translatable="yes">_URL</property>
|
||||
<property name="use-underline">True</property>
|
||||
<property name="mnemonic-widget">url_entry</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkEntry" id="url_entry">
|
||||
<property name="width-request">400</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="hexpand">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">1</property>
|
||||
<property name="top-attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<action-widgets>
|
||||
<action-widget response="-6">cancel_button</action-widget>
|
||||
<action-widget response="-3">open_button</action-widget>
|
||||
</action-widgets>
|
||||
</object>
|
||||
</interface>
|
37
gtk/Utils.cc
37
gtk/Utils.cc
|
@ -24,7 +24,6 @@
|
|||
#include <libtransmission/version.h> /* SHORT_VERSION_STRING */
|
||||
#include <libtransmission/web-utils.h>
|
||||
|
||||
#include "HigWorkarea.h"
|
||||
#include "Prefs.h"
|
||||
#include "PrefsDialog.h"
|
||||
#include "Session.h"
|
||||
|
@ -446,6 +445,13 @@ void gtr_combo_box_set_active_enum(Gtk::ComboBox& combo_box, int value)
|
|||
}
|
||||
|
||||
Gtk::ComboBox* gtr_combo_box_new_enum(std::vector<std::pair<Glib::ustring, int>> const& items)
|
||||
{
|
||||
auto w = Gtk::make_managed<Gtk::ComboBox>();
|
||||
gtr_combo_box_set_enum(*w, items);
|
||||
return w;
|
||||
}
|
||||
|
||||
void gtr_combo_box_set_enum(Gtk::ComboBox& combo, std::vector<std::pair<Glib::ustring, int>> const& items)
|
||||
{
|
||||
auto store = Gtk::ListStore::create(enum_combo_cols);
|
||||
|
||||
|
@ -456,12 +462,12 @@ Gtk::ComboBox* gtr_combo_box_new_enum(std::vector<std::pair<Glib::ustring, int>>
|
|||
(*iter)[enum_combo_cols.label] = label;
|
||||
}
|
||||
|
||||
auto w = Gtk::make_managed<Gtk::ComboBox>(static_cast<Glib::RefPtr<Gtk::TreeModel> const&>(store));
|
||||
auto* r = Gtk::make_managed<Gtk::CellRendererText>();
|
||||
w->pack_start(*r, true);
|
||||
w->add_attribute(r->property_text(), enum_combo_cols.label);
|
||||
combo.clear();
|
||||
combo.set_model(store);
|
||||
|
||||
return w;
|
||||
auto* r = Gtk::make_managed<Gtk::CellRendererText>();
|
||||
combo.pack_start(*r, true);
|
||||
combo.add_attribute(r->property_text(), enum_combo_cols.label);
|
||||
}
|
||||
|
||||
int gtr_combo_box_get_active_enum(Gtk::ComboBox const& combo_box)
|
||||
|
@ -478,11 +484,20 @@ int gtr_combo_box_get_active_enum(Gtk::ComboBox const& combo_box)
|
|||
|
||||
Gtk::ComboBox* gtr_priority_combo_new()
|
||||
{
|
||||
return gtr_combo_box_new_enum({
|
||||
{ _("High"), TR_PRI_HIGH },
|
||||
{ _("Normal"), TR_PRI_NORMAL },
|
||||
{ _("Low"), TR_PRI_LOW },
|
||||
});
|
||||
auto w = Gtk::make_managed<Gtk::ComboBox>();
|
||||
gtr_priority_combo_init(*w);
|
||||
return w;
|
||||
}
|
||||
|
||||
void gtr_priority_combo_init(Gtk::ComboBox& combo)
|
||||
{
|
||||
gtr_combo_box_set_enum(
|
||||
combo,
|
||||
{
|
||||
{ _("High"), TR_PRI_HIGH },
|
||||
{ _("Normal"), TR_PRI_NORMAL },
|
||||
{ _("Low"), TR_PRI_LOW },
|
||||
});
|
||||
}
|
||||
|
||||
/***
|
||||
|
|
18
gtk/Utils.h
18
gtk/Utils.h
|
@ -88,10 +88,12 @@ void gtr_dialog_set_content(Gtk::Dialog& dialog, Gtk::Widget& content);
|
|||
***/
|
||||
|
||||
Gtk::ComboBox* gtr_priority_combo_new();
|
||||
void gtr_priority_combo_init(Gtk::ComboBox& combo);
|
||||
#define gtr_priority_combo_get_value(w) gtr_combo_box_get_active_enum(w)
|
||||
#define gtr_priority_combo_set_value(w, val) gtr_combo_box_set_active_enum(w, val)
|
||||
|
||||
Gtk::ComboBox* gtr_combo_box_new_enum(std::vector<std::pair<Glib::ustring, int>> const& items);
|
||||
void gtr_combo_box_set_enum(Gtk::ComboBox& combo, std::vector<std::pair<Glib::ustring, int>> const& items);
|
||||
int gtr_combo_box_get_active_enum(Gtk::ComboBox const&);
|
||||
void gtr_combo_box_set_active_enum(Gtk::ComboBox&, int value);
|
||||
|
||||
|
@ -229,6 +231,22 @@ struct fmt::formatter<Glib::ustring> : formatter<std::string>
|
|||
}
|
||||
};
|
||||
|
||||
template<typename T, typename... ArgTs>
|
||||
T* gtr_get_widget(Glib::RefPtr<Gtk::Builder> const& builder, Glib::ustring const& name, ArgTs&&... args)
|
||||
{
|
||||
T* widget = nullptr;
|
||||
builder->get_widget(name, widget, std::forward<ArgTs>(args)...);
|
||||
return widget;
|
||||
}
|
||||
|
||||
template<typename T, typename... ArgTs>
|
||||
T* gtr_get_widget_derived(Glib::RefPtr<Gtk::Builder> const& builder, Glib::ustring const& name, ArgTs&&... args)
|
||||
{
|
||||
T* widget = nullptr;
|
||||
builder->get_widget_derived(name, widget, std::forward<ArgTs>(args)...);
|
||||
return widget;
|
||||
}
|
||||
|
||||
namespace Glib
|
||||
{
|
||||
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
.tr-workarea.frame {
|
||||
border-left-width: 0;
|
||||
border-right-width: 0;
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
.tr-small {
|
||||
font-size: small;
|
||||
}
|
|
@ -285,97 +285,6 @@
|
|||
</submenu>
|
||||
</menu>
|
||||
|
||||
<object class="GtkToolbar" id="main-window-toolbar">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<child>
|
||||
<object class="GtkToolButton">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="tooltip-text" translatable="yes">Open a torrent</property>
|
||||
<property name="is-important">True</property>
|
||||
<property name="action-name">win.open-torrent</property>
|
||||
<property name="label" translatable="yes">_Open</property>
|
||||
<property name="use-underline">True</property>
|
||||
<property name="icon-name">document-open</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="homogeneous">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkToolButton">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="tooltip-text" translatable="yes">Start torrent</property>
|
||||
<property name="action-name">win.torrent-start</property>
|
||||
<property name="label" translatable="yes">_Start</property>
|
||||
<property name="use-underline">True</property>
|
||||
<property name="icon-name">media-playback-start</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="homogeneous">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkToolButton">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="tooltip-text" translatable="yes">Pause torrent</property>
|
||||
<property name="action-name">win.torrent-stop</property>
|
||||
<property name="label" translatable="yes">_Pause</property>
|
||||
<property name="use-underline">True</property>
|
||||
<property name="icon-name">media-playback-pause</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="homogeneous">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkToolButton">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="action-name">win.remove-torrent</property>
|
||||
<property name="label" translatable="yes">Remove torrent</property>
|
||||
<property name="use-underline">True</property>
|
||||
<property name="icon-name">list-remove</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="homogeneous">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSeparatorToolItem">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="homogeneous">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkToolButton">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="tooltip-text" translatable="yes">Torrent properties</property>
|
||||
<property name="is-important">True</property>
|
||||
<property name="action-name">win.show-torrent-properties</property>
|
||||
<property name="label" translatable="yes">_Properties</property>
|
||||
<property name="use-underline">True</property>
|
||||
<property name="icon-name">document-properties</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="homogeneous">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
|
||||
<menu id="main-window-popup">
|
||||
<section>
|
||||
<item>
|
||||
|
|
|
@ -6,6 +6,20 @@
|
|||
<file alias="icons/scalable/actions/ratio-symbolic.svg">icons/ratio-symbolic.svg</file>
|
||||
<file alias="icons/scalable/actions/turtle-symbolic.svg">icons/turtle-symbolic.svg</file>
|
||||
<file alias="icons/scalable/apps/transmission.svg" compressed="true" preprocess="xml-stripblanks">icons/hicolor_apps_scalable_transmission.svg</file>
|
||||
<file compressed="true">transmission-ui.css</file>
|
||||
<file compressed="true" preprocess="xml-stripblanks">transmission-ui.xml</file>
|
||||
<file compressed="true" preprocess="xml-stripblanks">AddTrackerDialog.ui</file>
|
||||
<file compressed="true" preprocess="xml-stripblanks">DetailsDialog.ui</file>
|
||||
<file compressed="true" preprocess="xml-stripblanks">EditTrackersDialog.ui</file>
|
||||
<file compressed="true" preprocess="xml-stripblanks">FilterBar.ui</file>
|
||||
<file compressed="true" preprocess="xml-stripblanks">MainWindow.ui</file>
|
||||
<file compressed="true" preprocess="xml-stripblanks">MakeDialog.ui</file>
|
||||
<file compressed="true" preprocess="xml-stripblanks">MakeProgressDialog.ui</file>
|
||||
<file compressed="true" preprocess="xml-stripblanks">MessageLogWindow.ui</file>
|
||||
<file compressed="true" preprocess="xml-stripblanks">OptionsDialog.ui</file>
|
||||
<file compressed="true" preprocess="xml-stripblanks">PrefsDialog.ui</file>
|
||||
<file compressed="true" preprocess="xml-stripblanks">RelocateDialog.ui</file>
|
||||
<file compressed="true" preprocess="xml-stripblanks">StatsDialog.ui</file>
|
||||
<file compressed="true" preprocess="xml-stripblanks">TorrentUrlChooserDialog.ui</file>
|
||||
</gresource>
|
||||
</gresources>
|
||||
|
|
Loading…
Reference in New Issue