mirror of
https://github.com/transmission/transmission
synced 2025-01-30 19:03:04 +00:00
refactor: make variant_headers reusable to qt app. (#1369)
* refactor: make variant_headers reusable to qt app. Torrent.cc's `change()` template methods are generically useful to deal with tr_variant wrangling, but previously were only used in Torrent.cc. This PR moves them into a new API `VariantHelpers.h` for use by Prefs, Session, TorrentModel, etc.
This commit is contained in:
parent
7e1da2d8fe
commit
00be8d00d7
17 changed files with 675 additions and 527 deletions
|
@ -373,7 +373,7 @@ void tr_sessionGetDefaultSettings(tr_variant* d)
|
|||
tr_variantDictAddBool(d, TR_KEY_rpc_whitelist_enabled, true);
|
||||
tr_variantDictAddStr(d, TR_KEY_rpc_host_whitelist, TR_DEFAULT_RPC_HOST_WHITELIST);
|
||||
tr_variantDictAddBool(d, TR_KEY_rpc_host_whitelist_enabled, true);
|
||||
tr_variantDictAddInt(d, TR_KEY_rpc_port, atoi(TR_DEFAULT_RPC_PORT_STR));
|
||||
tr_variantDictAddInt(d, TR_KEY_rpc_port, TR_DEFAULT_RPC_PORT);
|
||||
tr_variantDictAddStr(d, TR_KEY_rpc_url, TR_DEFAULT_RPC_URL_STR);
|
||||
tr_variantDictAddBool(d, TR_KEY_scrape_paused_torrents_enabled, true);
|
||||
tr_variantDictAddStr(d, TR_KEY_script_torrent_done_filename, "");
|
||||
|
|
|
@ -113,6 +113,7 @@ char const* tr_getDefaultDownloadDir(void);
|
|||
#define TR_DEFAULT_RPC_WHITELIST "127.0.0.1,::1"
|
||||
#define TR_DEFAULT_RPC_HOST_WHITELIST ""
|
||||
#define TR_DEFAULT_RPC_PORT_STR "9091"
|
||||
#define TR_DEFAULT_RPC_PORT 9091
|
||||
#define TR_DEFAULT_RPC_URL_STR "/transmission/"
|
||||
#define TR_DEFAULT_PEER_PORT_STR "51413"
|
||||
#define TR_DEFAULT_PEER_SOCKET_TOS_STR "default"
|
||||
|
|
|
@ -47,6 +47,7 @@ set(${PROJECT_NAME}_SOURCES
|
|||
TrackerModel.cc
|
||||
TrackerModelFilter.cc
|
||||
Utils.cc
|
||||
VariantHelpers.cc
|
||||
WatchDir.cc
|
||||
)
|
||||
|
||||
|
@ -108,6 +109,7 @@ set(${PROJECT_NAME}_HEADERS
|
|||
TrackerModelFilter.h
|
||||
Typedefs.h
|
||||
Utils.h
|
||||
VariantHelpers.h
|
||||
WatchDir.h
|
||||
)
|
||||
|
||||
|
|
|
@ -15,6 +15,10 @@
|
|||
#include "FreeSpaceLabel.h"
|
||||
#include "RpcQueue.h"
|
||||
#include "Session.h"
|
||||
#include "VariantHelpers.h"
|
||||
|
||||
using ::trqt::variant_helpers::dictAdd;
|
||||
using ::trqt::variant_helpers::dictFind;
|
||||
|
||||
namespace
|
||||
{
|
||||
|
@ -65,7 +69,7 @@ void FreeSpaceLabel::onTimer()
|
|||
|
||||
tr_variant args;
|
||||
tr_variantInitDict(&args, 1);
|
||||
tr_variantDictAddStr(&args, TR_KEY_path, path_.toUtf8().constData());
|
||||
dictAdd(&args, TR_KEY_path, path_);
|
||||
|
||||
auto* q = new RpcQueue();
|
||||
|
||||
|
@ -76,14 +80,11 @@ void FreeSpaceLabel::onTimer()
|
|||
|
||||
q->add([this](RpcResponse const& r)
|
||||
{
|
||||
QString str;
|
||||
|
||||
// update the label
|
||||
int64_t bytes = -1;
|
||||
|
||||
if (tr_variantDictFindInt(r.args.get(), TR_KEY_size_bytes, &bytes) && bytes >= 0)
|
||||
auto const bytes = dictFind<int64_t>(r.args.get(), TR_KEY_size_bytes);
|
||||
if (bytes && *bytes > 1)
|
||||
{
|
||||
setText(tr("%1 free").arg(Formatter::sizeToString(bytes)));
|
||||
setText(tr("%1 free").arg(Formatter::sizeToString(*bytes)));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -91,11 +92,8 @@ void FreeSpaceLabel::onTimer()
|
|||
}
|
||||
|
||||
// update the tooltip
|
||||
size_t len = 0;
|
||||
char const* path = nullptr;
|
||||
tr_variantDictFindStr(r.args.get(), TR_KEY_path, &path, &len);
|
||||
str = QString::fromUtf8(path, len);
|
||||
setToolTip(QDir::toNativeSeparators(str));
|
||||
auto const path = dictFind<QString>(r.args.get(), TR_KEY_path);
|
||||
setToolTip(QDir::toNativeSeparators(path ? *path : QString()));
|
||||
|
||||
timer_.start();
|
||||
});
|
||||
|
|
|
@ -20,6 +20,10 @@
|
|||
#include "Session.h"
|
||||
#include "Torrent.h"
|
||||
#include "Utils.h"
|
||||
#include "VariantHelpers.h"
|
||||
|
||||
using ::trqt::variant_helpers::dictAdd;
|
||||
using ::trqt::variant_helpers::listAdd;
|
||||
|
||||
/***
|
||||
****
|
||||
|
@ -260,15 +264,15 @@ void OptionsDialog::onAccepted()
|
|||
download_dir = ui_.destinationEdit->text();
|
||||
}
|
||||
|
||||
tr_variantDictAddStr(&args, TR_KEY_download_dir, download_dir.toUtf8().constData());
|
||||
dictAdd(&args, TR_KEY_download_dir, download_dir);
|
||||
|
||||
// paused
|
||||
tr_variantDictAddBool(&args, TR_KEY_paused, !ui_.startCheck->isChecked());
|
||||
dictAdd(&args, TR_KEY_paused, !ui_.startCheck->isChecked());
|
||||
|
||||
// priority
|
||||
int const index = ui_.priorityCombo->currentIndex();
|
||||
int const priority = ui_.priorityCombo->itemData(index).toInt();
|
||||
tr_variantDictAddInt(&args, TR_KEY_bandwidthPriority, priority);
|
||||
dictAdd(&args, TR_KEY_bandwidthPriority, priority);
|
||||
|
||||
// files-unwanted
|
||||
int count = wanted_.count(false);
|
||||
|
@ -281,7 +285,7 @@ void OptionsDialog::onAccepted()
|
|||
{
|
||||
if (!wanted_.at(i))
|
||||
{
|
||||
tr_variantListAddInt(l, i);
|
||||
listAdd(l, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -297,7 +301,7 @@ void OptionsDialog::onAccepted()
|
|||
{
|
||||
if (priorities_.at(i) == TR_PRI_LOW)
|
||||
{
|
||||
tr_variantListAddInt(l, i);
|
||||
listAdd(l, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -313,7 +317,7 @@ void OptionsDialog::onAccepted()
|
|||
{
|
||||
if (priorities_.at(i) == TR_PRI_HIGH)
|
||||
{
|
||||
tr_variantListAddInt(l, i);
|
||||
listAdd(l, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
170
qt/Prefs.cc
170
qt/Prefs.cc
|
@ -20,6 +20,10 @@
|
|||
#include "CustomVariantType.h"
|
||||
#include "Prefs.h"
|
||||
#include "Utils.h"
|
||||
#include "VariantHelpers.h"
|
||||
|
||||
using ::trqt::variant_helpers::dictAdd;
|
||||
using ::trqt::variant_helpers::getValue;
|
||||
|
||||
/***
|
||||
****
|
||||
|
@ -150,69 +154,78 @@ Prefs::Prefs(QString config_dir) :
|
|||
|
||||
for (int i = 0; i < PREFS_COUNT; ++i)
|
||||
{
|
||||
double d;
|
||||
bool bool_val;
|
||||
int64_t int_val;
|
||||
char const* str;
|
||||
size_t str_len;
|
||||
tr_variant* b(tr_variantDictFind(&top, Items[i].key));
|
||||
|
||||
switch (Items[i].type)
|
||||
{
|
||||
case QVariant::Int:
|
||||
if (tr_variantGetInt(b, &int_val))
|
||||
{
|
||||
values_[i].setValue(static_cast<qlonglong>(int_val));
|
||||
auto const value = getValue<int64_t>(b);
|
||||
if (value)
|
||||
{
|
||||
values_[i].setValue(*value);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case CustomVariantType::SortModeType:
|
||||
if (tr_variantGetStr(b, &str, nullptr))
|
||||
{
|
||||
values_[i] = QVariant::fromValue(SortMode(QString::fromUtf8(str)));
|
||||
auto const value = getValue<QString>(b);
|
||||
if (value)
|
||||
{
|
||||
values_[i] = QVariant::fromValue(SortMode(*value));
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case CustomVariantType::FilterModeType:
|
||||
if (tr_variantGetStr(b, &str, nullptr))
|
||||
{
|
||||
values_[i] = QVariant::fromValue(FilterMode(QString::fromUtf8(str)));
|
||||
auto const value = getValue<QString>(b);
|
||||
if (value)
|
||||
{
|
||||
values_[i] = QVariant::fromValue(FilterMode(*value));
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case QVariant::String:
|
||||
if (tr_variantGetStr(b, &str, &str_len))
|
||||
{
|
||||
values_[i].setValue(QString::fromUtf8(str, str_len));
|
||||
auto const value = getValue<QString>(b);
|
||||
if (value)
|
||||
{
|
||||
values_[i].setValue(*value);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case QVariant::Bool:
|
||||
if (tr_variantGetBool(b, &bool_val))
|
||||
{
|
||||
values_[i].setValue(static_cast<bool>(bool_val));
|
||||
auto const value = getValue<bool>(b);
|
||||
if (value)
|
||||
{
|
||||
values_[i].setValue(*value);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case QVariant::Double:
|
||||
if (tr_variantGetReal(b, &d))
|
||||
{
|
||||
values_[i].setValue(d);
|
||||
auto const value = getValue<double>(b);
|
||||
if (value)
|
||||
{
|
||||
values_[i].setValue(*value);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case QVariant::DateTime:
|
||||
if (tr_variantGetInt(b, &int_val))
|
||||
{
|
||||
values_[i].setValue(QDateTime::fromTime_t(int_val));
|
||||
auto const value = getValue<time_t>(b);
|
||||
if (value)
|
||||
{
|
||||
values_[i].setValue(QDateTime::fromTime_t(*value));
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -243,44 +256,31 @@ Prefs::~Prefs()
|
|||
switch (Items[i].type)
|
||||
{
|
||||
case QVariant::Int:
|
||||
tr_variantDictAddInt(¤t_settings, key, val.toInt());
|
||||
dictAdd(¤t_settings, key, val.toInt());
|
||||
break;
|
||||
|
||||
case CustomVariantType::SortModeType:
|
||||
tr_variantDictAddStr(¤t_settings, key, val.value<SortMode>().name().toUtf8().constData());
|
||||
dictAdd(¤t_settings, key, val.value<SortMode>().name());
|
||||
break;
|
||||
|
||||
case CustomVariantType::FilterModeType:
|
||||
tr_variantDictAddStr(¤t_settings, key, val.value<FilterMode>().name().toUtf8().constData());
|
||||
dictAdd(¤t_settings, key, val.value<FilterMode>().name());
|
||||
break;
|
||||
|
||||
case QVariant::String:
|
||||
{
|
||||
QByteArray const ba(val.toByteArray());
|
||||
char const* s = ba.constData();
|
||||
|
||||
if (Utils::isValidUtf8(s))
|
||||
{
|
||||
tr_variantDictAddStr(¤t_settings, key, s);
|
||||
}
|
||||
else
|
||||
{
|
||||
tr_variantDictAddStr(¤t_settings, key, val.toString().toUtf8().constData());
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
dictAdd(¤t_settings, key, val.toString());
|
||||
break;
|
||||
|
||||
case QVariant::Bool:
|
||||
tr_variantDictAddBool(¤t_settings, key, val.toBool());
|
||||
dictAdd(¤t_settings, key, val.toBool());
|
||||
break;
|
||||
|
||||
case QVariant::Double:
|
||||
tr_variantDictAddReal(¤t_settings, key, val.toDouble());
|
||||
dictAdd(¤t_settings, key, val.toDouble());
|
||||
break;
|
||||
|
||||
case QVariant::DateTime:
|
||||
tr_variantDictAddInt(¤t_settings, key, val.toDateTime().toTime_t());
|
||||
dictAdd(¤t_settings, key, val.toDateTime().toTime_t());
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -313,45 +313,45 @@ Prefs::~Prefs()
|
|||
void Prefs::initDefaults(tr_variant* d)
|
||||
{
|
||||
tr_variantDictReserve(d, 38);
|
||||
tr_variantDictAddBool(d, TR_KEY_blocklist_updates_enabled, true);
|
||||
tr_variantDictAddBool(d, TR_KEY_compact_view, false);
|
||||
tr_variantDictAddBool(d, TR_KEY_inhibit_desktop_hibernation, false);
|
||||
tr_variantDictAddBool(d, TR_KEY_prompt_before_exit, true);
|
||||
tr_variantDictAddBool(d, TR_KEY_remote_session_enabled, false);
|
||||
tr_variantDictAddBool(d, TR_KEY_remote_session_requres_authentication, false);
|
||||
tr_variantDictAddBool(d, TR_KEY_show_backup_trackers, false);
|
||||
tr_variantDictAddBool(d, TR_KEY_show_extra_peer_details, false);
|
||||
tr_variantDictAddBool(d, TR_KEY_show_filterbar, true);
|
||||
tr_variantDictAddBool(d, TR_KEY_show_notification_area_icon, false);
|
||||
tr_variantDictAddBool(d, TR_KEY_start_minimized, false);
|
||||
tr_variantDictAddBool(d, TR_KEY_show_options_window, true);
|
||||
tr_variantDictAddBool(d, TR_KEY_show_statusbar, true);
|
||||
tr_variantDictAddBool(d, TR_KEY_show_toolbar, true);
|
||||
tr_variantDictAddBool(d, TR_KEY_show_tracker_scrapes, false);
|
||||
tr_variantDictAddBool(d, TR_KEY_sort_reversed, false);
|
||||
tr_variantDictAddBool(d, TR_KEY_torrent_added_notification_enabled, true);
|
||||
tr_variantDictAddBool(d, TR_KEY_torrent_complete_notification_enabled, true);
|
||||
tr_variantDictAddStr(d, TR_KEY_torrent_complete_sound_command,
|
||||
dictAdd(d, TR_KEY_blocklist_updates_enabled, true);
|
||||
dictAdd(d, TR_KEY_compact_view, false);
|
||||
dictAdd(d, TR_KEY_inhibit_desktop_hibernation, false);
|
||||
dictAdd(d, TR_KEY_prompt_before_exit, true);
|
||||
dictAdd(d, TR_KEY_remote_session_enabled, false);
|
||||
dictAdd(d, TR_KEY_remote_session_requres_authentication, false);
|
||||
dictAdd(d, TR_KEY_show_backup_trackers, false);
|
||||
dictAdd(d, TR_KEY_show_extra_peer_details, false);
|
||||
dictAdd(d, TR_KEY_show_filterbar, true);
|
||||
dictAdd(d, TR_KEY_show_notification_area_icon, false);
|
||||
dictAdd(d, TR_KEY_start_minimized, false);
|
||||
dictAdd(d, TR_KEY_show_options_window, true);
|
||||
dictAdd(d, TR_KEY_show_statusbar, true);
|
||||
dictAdd(d, TR_KEY_show_toolbar, true);
|
||||
dictAdd(d, TR_KEY_show_tracker_scrapes, false);
|
||||
dictAdd(d, TR_KEY_sort_reversed, false);
|
||||
dictAdd(d, TR_KEY_torrent_added_notification_enabled, true);
|
||||
dictAdd(d, TR_KEY_torrent_complete_notification_enabled, true);
|
||||
dictAdd(d, TR_KEY_torrent_complete_sound_command,
|
||||
"canberra-gtk-play -i complete-download -d 'transmission torrent downloaded'");
|
||||
tr_variantDictAddBool(d, TR_KEY_torrent_complete_sound_enabled, true);
|
||||
tr_variantDictAddBool(d, TR_KEY_user_has_given_informed_consent, false);
|
||||
tr_variantDictAddBool(d, TR_KEY_watch_dir_enabled, false);
|
||||
tr_variantDictAddInt(d, TR_KEY_blocklist_date, 0);
|
||||
tr_variantDictAddInt(d, TR_KEY_main_window_height, 500);
|
||||
tr_variantDictAddInt(d, TR_KEY_main_window_width, 300);
|
||||
tr_variantDictAddInt(d, TR_KEY_main_window_x, 50);
|
||||
tr_variantDictAddInt(d, TR_KEY_main_window_y, 50);
|
||||
tr_variantDictAddInt(d, TR_KEY_remote_session_port, strtol(TR_DEFAULT_RPC_PORT_STR, nullptr, 0));
|
||||
tr_variantDictAddStr(d, TR_KEY_download_dir, tr_getDefaultDownloadDir());
|
||||
tr_variantDictAddStr(d, TR_KEY_filter_mode, "all");
|
||||
tr_variantDictAddStr(d, TR_KEY_main_window_layout_order, "menu,toolbar,filter,list,statusbar");
|
||||
tr_variantDictAddStr(d, TR_KEY_open_dialog_dir, QDir::home().absolutePath().toUtf8());
|
||||
tr_variantDictAddStr(d, TR_KEY_remote_session_host, "localhost");
|
||||
tr_variantDictAddStr(d, TR_KEY_remote_session_password, "");
|
||||
tr_variantDictAddStr(d, TR_KEY_remote_session_username, "");
|
||||
tr_variantDictAddStr(d, TR_KEY_sort_mode, "sort-by-name");
|
||||
tr_variantDictAddStr(d, TR_KEY_statusbar_stats, "total-ratio");
|
||||
tr_variantDictAddStr(d, TR_KEY_watch_dir, tr_getDefaultDownloadDir());
|
||||
dictAdd(d, TR_KEY_torrent_complete_sound_enabled, true);
|
||||
dictAdd(d, TR_KEY_user_has_given_informed_consent, false);
|
||||
dictAdd(d, TR_KEY_watch_dir_enabled, false);
|
||||
dictAdd(d, TR_KEY_blocklist_date, 0);
|
||||
dictAdd(d, TR_KEY_main_window_height, 500);
|
||||
dictAdd(d, TR_KEY_main_window_width, 300);
|
||||
dictAdd(d, TR_KEY_main_window_x, 50);
|
||||
dictAdd(d, TR_KEY_main_window_y, 50);
|
||||
dictAdd(d, TR_KEY_remote_session_port, TR_DEFAULT_RPC_PORT);
|
||||
dictAdd(d, TR_KEY_download_dir, tr_getDefaultDownloadDir());
|
||||
dictAdd(d, TR_KEY_filter_mode, "all");
|
||||
dictAdd(d, TR_KEY_main_window_layout_order, "menu,toolbar,filter,list,statusbar");
|
||||
dictAdd(d, TR_KEY_open_dialog_dir, QDir::home().absolutePath().toUtf8());
|
||||
dictAdd(d, TR_KEY_remote_session_host, "localhost");
|
||||
dictAdd(d, TR_KEY_remote_session_password, "");
|
||||
dictAdd(d, TR_KEY_remote_session_username, "");
|
||||
dictAdd(d, TR_KEY_sort_mode, "sort-by-name");
|
||||
dictAdd(d, TR_KEY_statusbar_stats, "total-ratio");
|
||||
dictAdd(d, TR_KEY_watch_dir, tr_getDefaultDownloadDir());
|
||||
}
|
||||
|
||||
/***
|
||||
|
|
|
@ -144,11 +144,6 @@ public:
|
|||
return !isCore(key);
|
||||
}
|
||||
|
||||
char const* keyStr(int i) const
|
||||
{
|
||||
return tr_quark_get_string(Items[i].key, nullptr);
|
||||
}
|
||||
|
||||
tr_quark getKey(int i) const
|
||||
{
|
||||
return Items[i].key;
|
||||
|
@ -204,8 +199,7 @@ private:
|
|||
|
||||
void initDefaults(tr_variant*);
|
||||
|
||||
// Intentionally not implemented
|
||||
void set(int key, char const* value);
|
||||
void set(int key, char const* value) = delete;
|
||||
|
||||
QString const config_dir_;
|
||||
|
||||
|
|
|
@ -21,12 +21,17 @@
|
|||
#include <libtransmission/version.h> // LONG_VERSION_STRING
|
||||
|
||||
#include "RpcClient.h"
|
||||
#include "VariantHelpers.h"
|
||||
|
||||
// #define DEBUG_HTTP
|
||||
|
||||
#define REQUEST_DATA_PROPERTY_KEY "requestData"
|
||||
#define REQUEST_FUTUREINTERFACE_PROPERTY_KEY "requestReplyFutureInterface"
|
||||
|
||||
using ::trqt::variant_helpers::dictAdd;
|
||||
using ::trqt::variant_helpers::dictFind;
|
||||
using ::trqt::variant_helpers::variantInit;
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
|
@ -94,14 +99,16 @@ QUrl const& RpcClient::url() const
|
|||
|
||||
RpcResponseFuture RpcClient::exec(tr_quark method, tr_variant* args)
|
||||
{
|
||||
return exec(tr_quark_get_string(method, nullptr), args);
|
||||
auto len = size_t{};
|
||||
auto const* str = tr_quark_get_string(method, &len);
|
||||
return exec(std::string_view(str, len), args);
|
||||
}
|
||||
|
||||
RpcResponseFuture RpcClient::exec(char const* method, tr_variant* args)
|
||||
RpcResponseFuture RpcClient::exec(std::string_view method, tr_variant* args)
|
||||
{
|
||||
TrVariantPtr json = createVariant();
|
||||
tr_variantInitDict(json.get(), 3);
|
||||
tr_variantDictAddStr(json.get(), TR_KEY_method, method);
|
||||
dictAdd(json.get(), TR_KEY_method, method);
|
||||
|
||||
if (args != nullptr)
|
||||
{
|
||||
|
@ -162,7 +169,7 @@ void RpcClient::sendLocalRequest(TrVariantPtr json, QFutureInterface<RpcResponse
|
|||
RpcResponseFuture RpcClient::sendRequest(TrVariantPtr json)
|
||||
{
|
||||
int64_t tag = getNextTag();
|
||||
tr_variantDictAddInt(json.get(), TR_KEY_tag, tag);
|
||||
dictAdd(json.get(), TR_KEY_tag, tag);
|
||||
|
||||
QFutureInterface<RpcResponse> promise;
|
||||
promise.setExpectedResultCount(1);
|
||||
|
@ -205,7 +212,7 @@ void RpcClient::localSessionCallback(tr_session* s, tr_variant* response, void*
|
|||
|
||||
TrVariantPtr json = createVariant();
|
||||
*json = *response;
|
||||
tr_variantInitBool(response, false);
|
||||
variantInit(response, false);
|
||||
|
||||
// this callback is invoked in the libtransmission thread, so we don't want
|
||||
// to process the response here... let's push it over to the Qt thread.
|
||||
|
@ -281,26 +288,19 @@ void RpcClient::localRequestFinished(TrVariantPtr response)
|
|||
|
||||
int64_t RpcClient::parseResponseTag(tr_variant& json)
|
||||
{
|
||||
int64_t tag;
|
||||
|
||||
if (!tr_variantDictFindInt(&json, TR_KEY_tag, &tag))
|
||||
{
|
||||
tag = -1;
|
||||
}
|
||||
|
||||
return tag;
|
||||
auto const tag = dictFind<int>(&json, TR_KEY_tag);
|
||||
return tag ? *tag : -1;
|
||||
}
|
||||
|
||||
RpcResponse RpcClient::parseResponseData(tr_variant& json)
|
||||
{
|
||||
RpcResponse ret;
|
||||
|
||||
char const* result;
|
||||
|
||||
if (tr_variantDictFindStr(&json, TR_KEY_result, &result, nullptr))
|
||||
auto const result = dictFind<QString>(&json, TR_KEY_result);
|
||||
if (result)
|
||||
{
|
||||
ret.result = QString::fromUtf8(result);
|
||||
ret.success = std::strcmp(result, "success") == 0;
|
||||
ret.result = *result;
|
||||
ret.success = *result == QStringLiteral("success");
|
||||
}
|
||||
|
||||
tr_variant* args;
|
||||
|
@ -309,7 +309,7 @@ RpcResponse RpcClient::parseResponseData(tr_variant& json)
|
|||
{
|
||||
ret.args = createVariant();
|
||||
*ret.args = *args;
|
||||
tr_variantInitBool(args, false);
|
||||
variantInit(args, false);
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <string_view>
|
||||
|
||||
#include <QFuture>
|
||||
#include <QFutureInterface>
|
||||
|
@ -62,7 +63,7 @@ public:
|
|||
QUrl const& url() const;
|
||||
|
||||
RpcResponseFuture exec(tr_quark method, tr_variant* args);
|
||||
RpcResponseFuture exec(char const* method, tr_variant* args);
|
||||
RpcResponseFuture exec(std::string_view method, tr_variant* args);
|
||||
|
||||
signals:
|
||||
void httpAuthenticationRequired();
|
||||
|
|
244
qt/Session.cc
244
qt/Session.cc
|
@ -34,6 +34,12 @@
|
|||
#include "SessionDialog.h"
|
||||
#include "Torrent.h"
|
||||
#include "Utils.h"
|
||||
#include "VariantHelpers.h"
|
||||
|
||||
using ::trqt::variant_helpers::dictAdd;
|
||||
using ::trqt::variant_helpers::dictFind;
|
||||
using ::trqt::variant_helpers::getValue;
|
||||
using ::trqt::variant_helpers::listAdd;
|
||||
|
||||
/***
|
||||
****
|
||||
|
@ -44,16 +50,6 @@ namespace
|
|||
|
||||
using KeyList = Torrent::KeyList;
|
||||
|
||||
void addList(tr_variant* list, KeyList const& keys)
|
||||
{
|
||||
tr_variantListReserve(list, keys.size());
|
||||
|
||||
for (tr_quark const key : keys)
|
||||
{
|
||||
tr_variantListAddQuark(list, key);
|
||||
}
|
||||
}
|
||||
|
||||
// If this object is passed as "ids" (compared by address), then recently active torrents are queried.
|
||||
auto const RecentlyActiveIDs = torrent_ids_t{ -1 };
|
||||
|
||||
|
@ -70,19 +66,19 @@ void Session::sessionSet(tr_quark const key, QVariant const& value)
|
|||
switch (value.type())
|
||||
{
|
||||
case QVariant::Bool:
|
||||
tr_variantDictAddBool(&args, key, value.toBool());
|
||||
dictAdd(&args, key, value.toBool());
|
||||
break;
|
||||
|
||||
case QVariant::Int:
|
||||
tr_variantDictAddInt(&args, key, value.toInt());
|
||||
dictAdd(&args, key, value.toInt());
|
||||
break;
|
||||
|
||||
case QVariant::Double:
|
||||
tr_variantDictAddReal(&args, key, value.toDouble());
|
||||
dictAdd(&args, key, value.toDouble());
|
||||
break;
|
||||
|
||||
case QVariant::String:
|
||||
tr_variantDictAddStr(&args, key, value.toString().toUtf8().constData());
|
||||
dictAdd(&args, key, value.toString());
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -107,7 +103,11 @@ void Session::portTest()
|
|||
|
||||
if (r.success)
|
||||
{
|
||||
(void)tr_variantDictFindBool(r.args.get(), TR_KEY_port_is_open, &is_open);
|
||||
auto const value = dictFind<bool>(r.args.get(), TR_KEY_port_is_open);
|
||||
if (value)
|
||||
{
|
||||
is_open = *value;
|
||||
}
|
||||
}
|
||||
|
||||
emit portTested(is_open);
|
||||
|
@ -120,8 +120,8 @@ void Session::copyMagnetLinkToClipboard(int torrent_id)
|
|||
{
|
||||
tr_variant args;
|
||||
tr_variantInitDict(&args, 2);
|
||||
tr_variantListAddInt(tr_variantDictAddList(&args, TR_KEY_ids, 1), torrent_id);
|
||||
tr_variantListAddStr(tr_variantDictAddList(&args, TR_KEY_fields, 1), "magnetLink");
|
||||
dictAdd(&args, TR_KEY_ids, std::array<int, 1>{ torrent_id });
|
||||
dictAdd(&args, TR_KEY_fields, std::array<std::string_view, 1>{ "magnetLink" });
|
||||
|
||||
auto* q = new RpcQueue();
|
||||
|
||||
|
@ -140,11 +140,13 @@ void Session::copyMagnetLinkToClipboard(int torrent_id)
|
|||
}
|
||||
|
||||
tr_variant* const child = tr_variantListChild(torrents, 0);
|
||||
char const* str;
|
||||
|
||||
if (child != nullptr && tr_variantDictFindStr(child, TR_KEY_magnetLink, &str, nullptr))
|
||||
if (child != nullptr)
|
||||
{
|
||||
qApp->clipboard()->setText(QString::fromUtf8(str));
|
||||
auto const link = dictFind<QString>(child, TR_KEY_magnetLink);
|
||||
if (link)
|
||||
{
|
||||
qApp->clipboard()->setText(*link);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -407,16 +409,11 @@ void addOptionalIds(tr_variant* args, torrent_ids_t const& ids)
|
|||
{
|
||||
if (&ids == &RecentlyActiveIDs)
|
||||
{
|
||||
tr_variantDictAddStr(args, TR_KEY_ids, "recently-active");
|
||||
dictAdd(args, TR_KEY_ids, "recently-active");
|
||||
}
|
||||
else if (!ids.empty())
|
||||
{
|
||||
tr_variant* id_list(tr_variantDictAddList(args, TR_KEY_ids, ids.size()));
|
||||
|
||||
for (int const i : ids)
|
||||
{
|
||||
tr_variantListAddInt(id_list, i);
|
||||
}
|
||||
dictAdd(args, TR_KEY_ids, ids);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -426,8 +423,8 @@ void Session::torrentSet(torrent_ids_t const& ids, tr_quark const key, double va
|
|||
{
|
||||
tr_variant args;
|
||||
tr_variantInitDict(&args, 2);
|
||||
tr_variantDictAddReal(&args, key, value);
|
||||
addOptionalIds(&args, ids);
|
||||
dictAdd(&args, key, value);
|
||||
|
||||
exec(TR_KEY_torrent_set, &args);
|
||||
}
|
||||
|
@ -436,8 +433,8 @@ void Session::torrentSet(torrent_ids_t const& ids, tr_quark const key, int value
|
|||
{
|
||||
tr_variant args;
|
||||
tr_variantInitDict(&args, 2);
|
||||
tr_variantDictAddInt(&args, key, value);
|
||||
addOptionalIds(&args, ids);
|
||||
dictAdd(&args, key, value);
|
||||
|
||||
exec(TR_KEY_torrent_set, &args);
|
||||
}
|
||||
|
@ -446,8 +443,8 @@ void Session::torrentSet(torrent_ids_t const& ids, tr_quark const key, bool valu
|
|||
{
|
||||
tr_variant args;
|
||||
tr_variantInitDict(&args, 2);
|
||||
tr_variantDictAddBool(&args, key, value);
|
||||
addOptionalIds(&args, ids);
|
||||
dictAdd(&args, key, value);
|
||||
|
||||
exec(TR_KEY_torrent_set, &args);
|
||||
}
|
||||
|
@ -457,12 +454,7 @@ void Session::torrentSet(torrent_ids_t const& ids, tr_quark const key, QStringLi
|
|||
tr_variant args;
|
||||
tr_variantInitDict(&args, 2);
|
||||
addOptionalIds(&args, ids);
|
||||
tr_variant* list(tr_variantDictAddList(&args, key, value.size()));
|
||||
|
||||
for (QString const& str : value)
|
||||
{
|
||||
tr_variantListAddStr(list, str.toUtf8().constData());
|
||||
}
|
||||
dictAdd(&args, key, value);
|
||||
|
||||
exec(TR_KEY_torrent_set, &args);
|
||||
}
|
||||
|
@ -472,12 +464,7 @@ void Session::torrentSet(torrent_ids_t const& ids, tr_quark const key, QList<int
|
|||
tr_variant args;
|
||||
tr_variantInitDict(&args, 2);
|
||||
addOptionalIds(&args, ids);
|
||||
tr_variant* list(tr_variantDictAddList(&args, key, value.size()));
|
||||
|
||||
for (int const i : value)
|
||||
{
|
||||
tr_variantListAddInt(list, i);
|
||||
}
|
||||
dictAdd(&args, key, value);
|
||||
|
||||
exec(TR_KEY_torrent_set, &args);
|
||||
}
|
||||
|
@ -488,8 +475,8 @@ void Session::torrentSet(torrent_ids_t const& ids, tr_quark const key, QPair<int
|
|||
tr_variantInitDict(&args, 2);
|
||||
addOptionalIds(&args, ids);
|
||||
tr_variant* list(tr_variantDictAddList(&args, key, 2));
|
||||
tr_variantListAddInt(list, value.first);
|
||||
tr_variantListAddStr(list, value.second.toUtf8().constData());
|
||||
listAdd(list, value.first);
|
||||
listAdd(list, value.second);
|
||||
|
||||
exec(TR_KEY_torrent_set, &args);
|
||||
}
|
||||
|
@ -499,8 +486,8 @@ void Session::torrentSetLocation(torrent_ids_t const& ids, QString const& locati
|
|||
tr_variant args;
|
||||
tr_variantInitDict(&args, 3);
|
||||
addOptionalIds(&args, ids);
|
||||
tr_variantDictAddStr(&args, TR_KEY_location, location.toUtf8().constData());
|
||||
tr_variantDictAddBool(&args, TR_KEY_move, do_move);
|
||||
dictAdd(&args, TR_KEY_location, location);
|
||||
dictAdd(&args, TR_KEY_move, do_move);
|
||||
|
||||
exec(TR_KEY_torrent_set_location, &args);
|
||||
}
|
||||
|
@ -510,8 +497,8 @@ void Session::torrentRenamePath(torrent_ids_t const& ids, QString const& oldpath
|
|||
tr_variant args;
|
||||
tr_variantInitDict(&args, 2);
|
||||
addOptionalIds(&args, ids);
|
||||
tr_variantDictAddStr(&args, TR_KEY_path, oldpath.toUtf8().constData());
|
||||
tr_variantDictAddStr(&args, TR_KEY_name, newname.toUtf8().constData());
|
||||
dictAdd(&args, TR_KEY_path, oldpath);
|
||||
dictAdd(&args, TR_KEY_name, newname);
|
||||
|
||||
auto* q = new RpcQueue();
|
||||
|
||||
|
@ -521,14 +508,14 @@ void Session::torrentRenamePath(torrent_ids_t const& ids, QString const& oldpath
|
|||
},
|
||||
[](RpcResponse const& r)
|
||||
{
|
||||
char const* path = "(unknown)";
|
||||
char const* name = "(unknown)";
|
||||
tr_variantDictFindStr(r.args.get(), TR_KEY_path, &path, nullptr);
|
||||
tr_variantDictFindStr(r.args.get(), TR_KEY_name, &name, nullptr);
|
||||
auto str = dictFind<QString>(r.args.get(), TR_KEY_path);
|
||||
auto const path = str ? *str : QStringLiteral("(unknown)");
|
||||
str = dictFind<QString>(r.args.get(), TR_KEY_name);
|
||||
auto const name = str ? *str : QStringLiteral("(unknown)");
|
||||
|
||||
auto* d = new QMessageBox(QMessageBox::Information, tr("Error Renaming Path"),
|
||||
tr(R"(<p><b>Unable to rename "%1" as "%2": %3.</b></p><p>Please correct the errors and try again.</p>)").
|
||||
arg(QString::fromUtf8(path)).arg(QString::fromUtf8(name)).arg(r.result), QMessageBox::Close,
|
||||
arg(path).arg(name).arg(r.result), QMessageBox::Close,
|
||||
qApp->activeWindow());
|
||||
QObject::connect(d, &QMessageBox::rejected, d, &QMessageBox::deleteLater);
|
||||
d->show();
|
||||
|
@ -546,8 +533,18 @@ void Session::refreshTorrents(torrent_ids_t const& ids, KeyList const& keys)
|
|||
{
|
||||
tr_variant args;
|
||||
tr_variantInitDict(&args, 3);
|
||||
tr_variantDictAddStr(&args, TR_KEY_format, "table");
|
||||
addList(tr_variantDictAddList(&args, TR_KEY_fields, 0), keys);
|
||||
dictAdd(&args, TR_KEY_format, "table");
|
||||
|
||||
std::vector<std::string_view> keystrs;
|
||||
keystrs.reserve(keys.size());
|
||||
for (auto const& key : keys)
|
||||
{
|
||||
auto len = size_t{};
|
||||
auto const* str = tr_quark_get_string(key, &len);
|
||||
keystrs.emplace_back(str, len);
|
||||
}
|
||||
|
||||
dictAdd(&args, TR_KEY_fields, keystrs);
|
||||
addOptionalIds(&args, ids);
|
||||
|
||||
auto* q = new RpcQueue();
|
||||
|
@ -587,7 +584,7 @@ void Session::refreshExtraStats(torrent_ids_t const& ids)
|
|||
refreshTorrents(ids, Torrent::MainStatKeys + Torrent::DetailStatKeys);
|
||||
}
|
||||
|
||||
void Session::sendTorrentRequest(char const* request, torrent_ids_t const& ids)
|
||||
void Session::sendTorrentRequest(std::string_view request, torrent_ids_t const& ids)
|
||||
{
|
||||
tr_variant args;
|
||||
tr_variantInitDict(&args, 1);
|
||||
|
@ -703,11 +700,10 @@ void Session::updateBlocklist()
|
|||
|
||||
q->add([this](RpcResponse const& r)
|
||||
{
|
||||
int64_t blocklist_size;
|
||||
|
||||
if (tr_variantDictFindInt(r.args.get(), TR_KEY_blocklist_size, &blocklist_size))
|
||||
auto const size = dictFind<int>(r.args.get(), TR_KEY_blocklist_size);
|
||||
if (size)
|
||||
{
|
||||
setBlocklistSize(blocklist_size);
|
||||
setBlocklistSize(*size);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -723,38 +719,37 @@ RpcResponseFuture Session::exec(tr_quark method, tr_variant* args)
|
|||
return rpc_.exec(method, args);
|
||||
}
|
||||
|
||||
RpcResponseFuture Session::exec(char const* method, tr_variant* args)
|
||||
RpcResponseFuture Session::exec(std::string_view method, tr_variant* args)
|
||||
{
|
||||
return rpc_.exec(method, args);
|
||||
}
|
||||
|
||||
void Session::updateStats(tr_variant* d, tr_session_stats* stats)
|
||||
{
|
||||
int64_t i;
|
||||
|
||||
if (tr_variantDictFindInt(d, TR_KEY_uploadedBytes, &i))
|
||||
auto value = dictFind<int>(d, TR_KEY_uploadedBytes);
|
||||
if (value)
|
||||
{
|
||||
stats->uploadedBytes = i;
|
||||
stats->uploadedBytes = *value;
|
||||
}
|
||||
|
||||
if (tr_variantDictFindInt(d, TR_KEY_downloadedBytes, &i))
|
||||
if ((value = dictFind<int>(d, TR_KEY_downloadedBytes)))
|
||||
{
|
||||
stats->downloadedBytes = i;
|
||||
stats->downloadedBytes = *value;
|
||||
}
|
||||
|
||||
if (tr_variantDictFindInt(d, TR_KEY_filesAdded, &i))
|
||||
if ((value = dictFind<int>(d, TR_KEY_filesAdded)))
|
||||
{
|
||||
stats->filesAdded = i;
|
||||
stats->filesAdded = *value;
|
||||
}
|
||||
|
||||
if (tr_variantDictFindInt(d, TR_KEY_sessionCount, &i))
|
||||
if ((value = dictFind<int>(d, TR_KEY_sessionCount)))
|
||||
{
|
||||
stats->sessionCount = i;
|
||||
stats->sessionCount = *value;
|
||||
}
|
||||
|
||||
if (tr_variantDictFindInt(d, TR_KEY_secondsActive, &i))
|
||||
if ((value = dictFind<int>(d, TR_KEY_secondsActive)))
|
||||
{
|
||||
stats->secondsActive = i;
|
||||
stats->secondsActive = *value;
|
||||
}
|
||||
|
||||
stats->ratio = tr_getRatio(stats->uploadedBytes, stats->downloadedBytes);
|
||||
|
@ -779,9 +774,6 @@ void Session::updateStats(tr_variant* d)
|
|||
|
||||
void Session::updateInfo(tr_variant* d)
|
||||
{
|
||||
int64_t i;
|
||||
char const* str;
|
||||
|
||||
disconnect(&prefs_, SIGNAL(changed(int)), this, SLOT(updatePref(int)));
|
||||
|
||||
for (int i = Prefs::FIRST_CORE_PREF; i <= Prefs::LAST_CORE_PREF; ++i)
|
||||
|
@ -795,19 +787,19 @@ void Session::updateInfo(tr_variant* d)
|
|||
|
||||
if (i == Prefs::ENCRYPTION)
|
||||
{
|
||||
char const* val;
|
||||
auto const str = getValue<QString>(b);
|
||||
|
||||
if (tr_variantGetStr(b, &val, nullptr))
|
||||
if (str)
|
||||
{
|
||||
if (qstrcmp(val, "required") == 0)
|
||||
if (*str == QStringLiteral("required"))
|
||||
{
|
||||
prefs_.set(i, 2);
|
||||
}
|
||||
else if (qstrcmp(val, "preferred") == 0)
|
||||
else if (*str == QStringLiteral("preferred"))
|
||||
{
|
||||
prefs_.set(i, 1);
|
||||
}
|
||||
else if (qstrcmp(val, "tolerated") == 0)
|
||||
else if (*str == QStringLiteral("tolerated"))
|
||||
{
|
||||
prefs_.set(i, 0);
|
||||
}
|
||||
|
@ -820,11 +812,11 @@ void Session::updateInfo(tr_variant* d)
|
|||
{
|
||||
case QVariant::Int:
|
||||
{
|
||||
int64_t val;
|
||||
auto const value = getValue<int>(b);
|
||||
|
||||
if (tr_variantGetInt(b, &val))
|
||||
if (value)
|
||||
{
|
||||
prefs_.set(i, static_cast<int>(val));
|
||||
prefs_.set(i, *value);
|
||||
}
|
||||
|
||||
break;
|
||||
|
@ -832,11 +824,11 @@ void Session::updateInfo(tr_variant* d)
|
|||
|
||||
case QVariant::Double:
|
||||
{
|
||||
double val;
|
||||
auto const value = getValue<double>(b);
|
||||
|
||||
if (tr_variantGetReal(b, &val))
|
||||
if (value)
|
||||
{
|
||||
prefs_.set(i, val);
|
||||
prefs_.set(i, *value);
|
||||
}
|
||||
|
||||
break;
|
||||
|
@ -844,11 +836,11 @@ void Session::updateInfo(tr_variant* d)
|
|||
|
||||
case QVariant::Bool:
|
||||
{
|
||||
bool val;
|
||||
auto const value = getValue<bool>(b);
|
||||
|
||||
if (tr_variantGetBool(b, &val))
|
||||
if (value)
|
||||
{
|
||||
prefs_.set(i, val);
|
||||
prefs_.set(i, *value);
|
||||
}
|
||||
|
||||
break;
|
||||
|
@ -858,11 +850,11 @@ void Session::updateInfo(tr_variant* d)
|
|||
case CustomVariantType::SortModeType:
|
||||
case QVariant::String:
|
||||
{
|
||||
char const* val;
|
||||
auto const value = getValue<QString>(b);
|
||||
|
||||
if (tr_variantGetStr(b, &val, nullptr))
|
||||
if (value)
|
||||
{
|
||||
prefs_.set(i, QString::fromUtf8(val));
|
||||
prefs_.set(i, *value);
|
||||
}
|
||||
|
||||
break;
|
||||
|
@ -873,17 +865,16 @@ void Session::updateInfo(tr_variant* d)
|
|||
}
|
||||
}
|
||||
|
||||
bool b;
|
||||
double x;
|
||||
|
||||
if (tr_variantDictFindBool(d, TR_KEY_seedRatioLimited, &b))
|
||||
auto const b = dictFind<bool>(d, TR_KEY_seedRatioLimited);
|
||||
if (b)
|
||||
{
|
||||
prefs_.set(Prefs::RATIO_ENABLED, b);
|
||||
prefs_.set(Prefs::RATIO_ENABLED, *b);
|
||||
}
|
||||
|
||||
if (tr_variantDictFindReal(d, TR_KEY_seedRatioLimit, &x))
|
||||
auto const x = dictFind<double>(d, TR_KEY_seedRatioLimit);
|
||||
if (x)
|
||||
{
|
||||
prefs_.set(Prefs::RATIO, x);
|
||||
prefs_.set(Prefs::RATIO, *x);
|
||||
}
|
||||
|
||||
/* Use the C API to get settings that, for security reasons, aren't supported by RPC */
|
||||
|
@ -898,25 +889,23 @@ void Session::updateInfo(tr_variant* d)
|
|||
prefs_.set(Prefs::RPC_WHITELIST, QString::fromUtf8(tr_sessionGetRPCWhitelist(session_)));
|
||||
}
|
||||
|
||||
if (tr_variantDictFindInt(d, TR_KEY_blocklist_size, &i) && i != blocklistSize())
|
||||
auto const size = dictFind<int>(d, TR_KEY_blocklist_size);
|
||||
if (size && *size != blocklistSize())
|
||||
{
|
||||
setBlocklistSize(i);
|
||||
setBlocklistSize(*size);
|
||||
}
|
||||
|
||||
if (tr_variantDictFindStr(d, TR_KEY_version, &str, nullptr) && session_version_ != QString::fromUtf8(str))
|
||||
auto str = dictFind<QString>(d, TR_KEY_version);
|
||||
if (str)
|
||||
{
|
||||
session_version_ = QString::fromUtf8(str);
|
||||
session_version_ = *str;
|
||||
}
|
||||
|
||||
if (tr_variantDictFindStr(d, TR_KEY_session_id, &str, nullptr))
|
||||
str = dictFind<QString>(d, TR_KEY_session_id);
|
||||
if (str)
|
||||
{
|
||||
QString const session_id = QString::fromUtf8(str);
|
||||
|
||||
if (session_id_ != session_id)
|
||||
{
|
||||
session_id_ = session_id;
|
||||
is_definitely_local_session_ = tr_session_id_is_local(str);
|
||||
}
|
||||
session_id_ = *str;
|
||||
is_definitely_local_session_ = tr_session_id_is_local(session_id_.toUtf8().constData());
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -943,26 +932,23 @@ void Session::addTorrent(AddData const& add_me, tr_variant* args, bool trash_ori
|
|||
|
||||
if (tr_variantDictFind(args, TR_KEY_paused) == nullptr)
|
||||
{
|
||||
tr_variantDictAddBool(args, TR_KEY_paused, !prefs_.getBool(Prefs::START));
|
||||
dictAdd(args, TR_KEY_paused, !prefs_.getBool(Prefs::START));
|
||||
}
|
||||
|
||||
switch (add_me.type)
|
||||
{
|
||||
case AddData::MAGNET:
|
||||
tr_variantDictAddStr(args, TR_KEY_filename, add_me.magnet.toUtf8().constData());
|
||||
dictAdd(args, TR_KEY_filename, add_me.magnet);
|
||||
break;
|
||||
|
||||
case AddData::URL:
|
||||
tr_variantDictAddStr(args, TR_KEY_filename, add_me.url.toString().toUtf8().constData());
|
||||
dictAdd(args, TR_KEY_filename, add_me.url.toString());
|
||||
break;
|
||||
|
||||
case AddData::FILENAME: /* fall-through */
|
||||
case AddData::METAINFO:
|
||||
{
|
||||
QByteArray const b64 = add_me.toBase64();
|
||||
tr_variantDictAddRaw(args, TR_KEY_metainfo, b64.constData(), b64.size());
|
||||
break;
|
||||
}
|
||||
dictAdd(args, TR_KEY_metainfo, add_me.toBase64());
|
||||
break;
|
||||
|
||||
default:
|
||||
qWarning() << "Unhandled AddData type: " << add_me.type;
|
||||
|
@ -993,14 +979,12 @@ void Session::addTorrent(AddData const& add_me, tr_variant* args, bool trash_ori
|
|||
return;
|
||||
}
|
||||
|
||||
char const* str;
|
||||
|
||||
if (tr_variantDictFindStr(dup, TR_KEY_name, &str, nullptr))
|
||||
auto const name = dictFind<QString>(dup, TR_KEY_name);
|
||||
if (name)
|
||||
{
|
||||
QString const name = QString::fromUtf8(str);
|
||||
auto* d = new QMessageBox(QMessageBox::Warning, tr("Add Torrent"),
|
||||
tr(R"(<p><b>Unable to add "%1".</b></p><p>It is a duplicate of "%2" which is already added.</p>)").
|
||||
arg(add_me.readableShortName()).arg(name), QMessageBox::Close, qApp->activeWindow());
|
||||
arg(add_me.readableShortName()).arg(*name), QMessageBox::Close, qApp->activeWindow());
|
||||
QObject::connect(d, &QMessageBox::rejected, d, &QMessageBox::deleteLater);
|
||||
d->show();
|
||||
}
|
||||
|
@ -1033,9 +1017,9 @@ void Session::addNewlyCreatedTorrent(QString const& filename, QString const& loc
|
|||
|
||||
tr_variant args;
|
||||
tr_variantInitDict(&args, 3);
|
||||
tr_variantDictAddStr(&args, TR_KEY_download_dir, local_path.toUtf8().constData());
|
||||
tr_variantDictAddBool(&args, TR_KEY_paused, !prefs_.getBool(Prefs::START));
|
||||
tr_variantDictAddRaw(&args, TR_KEY_metainfo, b64.constData(), b64.size());
|
||||
dictAdd(&args, TR_KEY_download_dir, local_path);
|
||||
dictAdd(&args, TR_KEY_paused, !prefs_.getBool(Prefs::START));
|
||||
dictAdd(&args, TR_KEY_metainfo, b64);
|
||||
|
||||
exec("torrent-add", &args);
|
||||
}
|
||||
|
@ -1047,7 +1031,7 @@ void Session::removeTorrents(torrent_ids_t const& ids, bool delete_files)
|
|||
tr_variant args;
|
||||
tr_variantInitDict(&args, 2);
|
||||
addOptionalIds(&args, ids);
|
||||
tr_variantDictAddInt(&args, TR_KEY_delete_local_data, delete_files);
|
||||
dictAdd(&args, TR_KEY_delete_local_data, delete_files);
|
||||
|
||||
exec("torrent-remove", &args);
|
||||
}
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <string_view>
|
||||
|
||||
#include <QObject>
|
||||
#include <QString>
|
||||
#include <QStringList>
|
||||
|
@ -75,7 +77,7 @@ public:
|
|||
bool isLocal() const;
|
||||
|
||||
RpcResponseFuture exec(tr_quark method, tr_variant* args);
|
||||
RpcResponseFuture exec(char const* method, tr_variant* args);
|
||||
RpcResponseFuture exec(std::string_view method, tr_variant* args);
|
||||
|
||||
void torrentSet(torrent_ids_t const& ids, tr_quark const key, bool val);
|
||||
void torrentSet(torrent_ids_t const& ids, tr_quark const key, int val);
|
||||
|
@ -131,7 +133,7 @@ private:
|
|||
|
||||
void sessionSet(tr_quark const key, QVariant const& variant);
|
||||
void pumpRequests();
|
||||
void sendTorrentRequest(char const* request, torrent_ids_t const& torrent_ids);
|
||||
void sendTorrentRequest(std::string_view request, torrent_ids_t const& torrent_ids);
|
||||
void refreshTorrents(torrent_ids_t const& torrent_ids, Torrent::KeyList const& keys);
|
||||
|
||||
static void updateStats(tr_variant* d, tr_session_stats* stats);
|
||||
|
|
245
qt/Torrent.cc
245
qt/Torrent.cc
|
@ -22,6 +22,9 @@
|
|||
#include "Prefs.h"
|
||||
#include "Torrent.h"
|
||||
#include "Utils.h"
|
||||
#include "VariantHelpers.h"
|
||||
|
||||
using ::trqt::variant_helpers::change;
|
||||
|
||||
/***
|
||||
****
|
||||
|
@ -120,248 +123,6 @@ Torrent::Torrent(Prefs const& prefs, int id) :
|
|||
****
|
||||
***/
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
template<typename T>
|
||||
bool change(T& setme, T const& value)
|
||||
{
|
||||
bool const changed = setme != value;
|
||||
|
||||
if (changed)
|
||||
{
|
||||
setme = value;
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
bool change(double& setme, double const& value)
|
||||
{
|
||||
bool const changed = !qFuzzyCompare(setme + 1, value + 1);
|
||||
|
||||
if (changed)
|
||||
{
|
||||
setme = value;
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
bool change(double& setme, tr_variant const* value)
|
||||
{
|
||||
double d;
|
||||
return tr_variantGetReal(value, &d) && change(setme, d);
|
||||
}
|
||||
|
||||
bool change(int& setme, tr_variant const* value)
|
||||
{
|
||||
int64_t i;
|
||||
return tr_variantGetInt(value, &i) && change(setme, static_cast<int>(i));
|
||||
}
|
||||
|
||||
bool change(uint64_t& setme, tr_variant const* value)
|
||||
{
|
||||
int64_t i;
|
||||
return tr_variantGetInt(value, &i) && change(setme, static_cast<uint64_t>(i));
|
||||
}
|
||||
|
||||
bool change(time_t& setme, tr_variant const* value)
|
||||
{
|
||||
int64_t i;
|
||||
return tr_variantGetInt(value, &i) && change(setme, static_cast<time_t>(i));
|
||||
}
|
||||
|
||||
bool change(Speed& setme, tr_variant const* value)
|
||||
{
|
||||
int64_t i;
|
||||
return tr_variantGetInt(value, &i) && change(setme, Speed::fromBps(i));
|
||||
}
|
||||
|
||||
bool change(bool& setme, tr_variant const* value)
|
||||
{
|
||||
bool b;
|
||||
return tr_variantGetBool(value, &b) && change(setme, b);
|
||||
}
|
||||
|
||||
bool change(QString& setme, tr_variant const* value)
|
||||
{
|
||||
bool changed = false;
|
||||
char const* str;
|
||||
size_t len;
|
||||
|
||||
if (!tr_variantGetStr(value, &str, &len))
|
||||
{
|
||||
return changed;
|
||||
}
|
||||
|
||||
if (len == 0)
|
||||
{
|
||||
changed = !setme.isEmpty();
|
||||
setme.clear();
|
||||
return changed;
|
||||
}
|
||||
|
||||
return change(setme, QString::fromUtf8(str, len));
|
||||
}
|
||||
|
||||
bool change(Peer& setme, tr_variant const* value)
|
||||
{
|
||||
bool changed = false;
|
||||
|
||||
size_t pos = 0;
|
||||
tr_quark key;
|
||||
tr_variant* child;
|
||||
while (tr_variantDictChild(const_cast<tr_variant*>(value), pos++, &key, &child))
|
||||
{
|
||||
switch (key)
|
||||
{
|
||||
#define HANDLE_KEY(key, field) case TR_KEY_ ## key: \
|
||||
changed = change(setme.field, child) || changed; break;
|
||||
|
||||
HANDLE_KEY(address, address)
|
||||
HANDLE_KEY(clientIsChoked, client_is_choked)
|
||||
HANDLE_KEY(clientIsInterested, client_is_interested)
|
||||
HANDLE_KEY(clientName, client_name)
|
||||
HANDLE_KEY(flagStr, flags)
|
||||
HANDLE_KEY(isDownloadingFrom, is_downloading_from)
|
||||
HANDLE_KEY(isEncrypted, is_encrypted)
|
||||
HANDLE_KEY(isIncoming, is_incoming)
|
||||
HANDLE_KEY(isUploadingTo, is_uploading_to)
|
||||
HANDLE_KEY(peerIsChoked, peer_is_choked)
|
||||
HANDLE_KEY(peerIsInterested, peer_is_interested)
|
||||
HANDLE_KEY(port, port)
|
||||
HANDLE_KEY(progress, progress)
|
||||
HANDLE_KEY(rateToClient, rate_to_client)
|
||||
HANDLE_KEY(rateToPeer, rate_to_peer)
|
||||
#undef HANDLE_KEY
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
bool change(TorrentFile& setme, tr_variant const* value)
|
||||
{
|
||||
bool changed = false;
|
||||
|
||||
size_t pos = 0;
|
||||
tr_quark key;
|
||||
tr_variant* child;
|
||||
while (tr_variantDictChild(const_cast<tr_variant*>(value), pos++, &key, &child))
|
||||
{
|
||||
switch (key)
|
||||
{
|
||||
#define HANDLE_KEY(key) case TR_KEY_ ## key: \
|
||||
changed = change(setme.key, child) || changed; break;
|
||||
|
||||
HANDLE_KEY(have)
|
||||
HANDLE_KEY(priority)
|
||||
HANDLE_KEY(wanted)
|
||||
#undef HANDLE_KEY
|
||||
#define HANDLE_KEY(key, field) case TR_KEY_ ## key: \
|
||||
changed = change(setme.field, child) || changed; break;
|
||||
|
||||
HANDLE_KEY(bytesCompleted, have)
|
||||
HANDLE_KEY(length, size)
|
||||
HANDLE_KEY(name, filename)
|
||||
#undef HANDLE_KEY
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
bool change(TrackerStat& setme, tr_variant const* value)
|
||||
{
|
||||
bool changed = false;
|
||||
|
||||
size_t pos = 0;
|
||||
tr_quark key;
|
||||
tr_variant* child;
|
||||
while (tr_variantDictChild(const_cast<tr_variant*>(value), pos++, &key, &child))
|
||||
{
|
||||
bool field_changed = false;
|
||||
|
||||
switch (key)
|
||||
{
|
||||
#define HANDLE_KEY(key, field) case TR_KEY_ ## key: \
|
||||
field_changed = change(setme.field, child); break;
|
||||
HANDLE_KEY(announce, announce)
|
||||
HANDLE_KEY(announceState, announce_state)
|
||||
HANDLE_KEY(downloadCount, download_count)
|
||||
HANDLE_KEY(hasAnnounced, has_announced)
|
||||
HANDLE_KEY(hasScraped, has_scraped)
|
||||
HANDLE_KEY(host, host);
|
||||
HANDLE_KEY(id, id);
|
||||
HANDLE_KEY(isBackup, is_backup);
|
||||
HANDLE_KEY(lastAnnouncePeerCount, last_announce_peer_count);
|
||||
HANDLE_KEY(lastAnnounceResult, last_announce_result);
|
||||
HANDLE_KEY(lastAnnounceStartTime, last_announce_start_time)
|
||||
HANDLE_KEY(lastAnnounceSucceeded, last_announce_succeeded)
|
||||
HANDLE_KEY(lastAnnounceTime, last_announce_time)
|
||||
HANDLE_KEY(lastAnnounceTimedOut, last_announce_timed_out)
|
||||
HANDLE_KEY(lastScrapeResult, last_scrape_result)
|
||||
HANDLE_KEY(lastScrapeStartTime, last_scrape_start_time)
|
||||
HANDLE_KEY(lastScrapeSucceeded, last_scrape_succeeded)
|
||||
HANDLE_KEY(lastScrapeTime, last_scrape_time)
|
||||
HANDLE_KEY(lastScrapeTimedOut, last_scrape_timed_out)
|
||||
HANDLE_KEY(leecherCount, leecher_count)
|
||||
HANDLE_KEY(nextAnnounceTime, next_announce_time)
|
||||
HANDLE_KEY(nextScrapeTime, next_scrape_time)
|
||||
HANDLE_KEY(scrapeState, scrape_state)
|
||||
HANDLE_KEY(seederCount, seeder_count)
|
||||
HANDLE_KEY(tier, tier)
|
||||
|
||||
#undef HANDLE_KEY
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (field_changed)
|
||||
{
|
||||
if (key == TR_KEY_announce)
|
||||
{
|
||||
setme.favicon_key = qApp->faviconCache().add(QUrl(setme.announce));
|
||||
}
|
||||
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool change(QVector<T>& setme, tr_variant const* value)
|
||||
{
|
||||
bool changed = false;
|
||||
|
||||
int const n = tr_variantListSize(value);
|
||||
if (setme.size() != n)
|
||||
{
|
||||
setme.resize(n);
|
||||
changed = true;
|
||||
}
|
||||
|
||||
for (int i = 0; i < n; ++i)
|
||||
{
|
||||
changed = change(setme[i], tr_variantListChild(const_cast<tr_variant*>(value), i)) || changed;
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
/***
|
||||
****
|
||||
***/
|
||||
|
||||
bool Torrent::getSeedRatio(double& setmeRatio) const
|
||||
{
|
||||
bool is_limited;
|
||||
|
|
|
@ -17,6 +17,9 @@
|
|||
#include "Torrent.h"
|
||||
#include "TorrentDelegate.h"
|
||||
#include "TorrentModel.h"
|
||||
#include "VariantHelpers.h"
|
||||
|
||||
using ::trqt::variant_helpers::getValue;
|
||||
|
||||
/***
|
||||
****
|
||||
|
@ -131,17 +134,14 @@ void TorrentModel::removeTorrents(tr_variant* list)
|
|||
tr_variant* child;
|
||||
while ((child = tr_variantListChild(list, i++)) != nullptr)
|
||||
{
|
||||
int64_t id;
|
||||
Torrent* torrent = nullptr;
|
||||
|
||||
if (tr_variantGetInt(child, &id))
|
||||
auto const id = getValue<int>(child);
|
||||
if (id)
|
||||
{
|
||||
torrent = getTorrentFromId(id);
|
||||
}
|
||||
|
||||
if (torrent != nullptr)
|
||||
{
|
||||
torrents.push_back(torrent);
|
||||
auto* torrent = getTorrentFromId(*id);
|
||||
if (torrent != nullptr)
|
||||
{
|
||||
torrents.push_back(torrent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -242,18 +242,18 @@ void TorrentModel::updateTorrents(tr_variant* torrents, bool is_complete_list)
|
|||
}
|
||||
|
||||
// Find the torrent id
|
||||
int64_t id;
|
||||
if (!tr_variantGetInt(values[id_pos], &id))
|
||||
auto const id = getValue<int>(values[id_pos]);
|
||||
if (!id)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
Torrent* tor = getTorrentFromId(id);
|
||||
Torrent* tor = getTorrentFromId(*id);
|
||||
bool is_new = false;
|
||||
|
||||
if (tor == nullptr)
|
||||
{
|
||||
tor = new Torrent(prefs_, id);
|
||||
tor = new Torrent(prefs_, *id);
|
||||
instantiated.push_back(tor);
|
||||
is_new = true;
|
||||
}
|
||||
|
@ -263,28 +263,28 @@ void TorrentModel::updateTorrents(tr_variant* torrents, bool is_complete_list)
|
|||
if (fields.any())
|
||||
{
|
||||
changed_fields |= fields;
|
||||
changed.insert(id);
|
||||
changed.insert(*id);
|
||||
}
|
||||
|
||||
if (fields.test(Torrent::EDIT_DATE))
|
||||
{
|
||||
edited.insert(id);
|
||||
edited.insert(*id);
|
||||
}
|
||||
|
||||
if (is_new && !tor->hasName())
|
||||
{
|
||||
needinfo.insert(id);
|
||||
needinfo.insert(*id);
|
||||
}
|
||||
|
||||
if (recently_added(tor) && tor->hasName() && !already_added_.count(id))
|
||||
if (recently_added(tor) && tor->hasName() && !already_added_.count(*id))
|
||||
{
|
||||
added.insert(id);
|
||||
already_added_.insert(id);
|
||||
added.insert(*id);
|
||||
already_added_.insert(*id);
|
||||
}
|
||||
|
||||
if (fields.test(Torrent::LEFT_UNTIL_DONE) && (tor->leftUntilDone() == 0) && (tor->downloadedEver() > 0))
|
||||
{
|
||||
completed.insert(id);
|
||||
completed.insert(*id);
|
||||
}
|
||||
|
||||
processed.push_back(tor);
|
||||
|
|
213
qt/VariantHelpers.cc
Normal file
213
qt/VariantHelpers.cc
Normal file
|
@ -0,0 +1,213 @@
|
|||
/*
|
||||
* This file Copyright (C) 2020 Mnemosyne LLC
|
||||
*
|
||||
* It may be used under the GNU GPL versions 2 or 3
|
||||
* or any future license endorsed by Mnemosyne LLC.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "VariantHelpers.h"
|
||||
|
||||
#include <QtGlobal> // qFuzzyCompare
|
||||
#include <QUrl>
|
||||
|
||||
#include "Application.h" // qApp
|
||||
#include "Filters.h"
|
||||
#include "Speed.h"
|
||||
#include "Torrent.h"
|
||||
|
||||
namespace trqt::variant_helpers
|
||||
{
|
||||
|
||||
bool change(double& setme, double const& value)
|
||||
{
|
||||
bool const changed = !qFuzzyCompare(setme + 1, value + 1);
|
||||
|
||||
if (changed)
|
||||
{
|
||||
setme = value;
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
bool change(Speed& setme, tr_variant const* variant)
|
||||
{
|
||||
auto const value = getValue<int>(variant);
|
||||
return value && change(setme, Speed::fromBps(*value));
|
||||
}
|
||||
|
||||
bool change(Peer& setme, tr_variant const* value)
|
||||
{
|
||||
bool changed = false;
|
||||
|
||||
size_t pos = 0;
|
||||
tr_quark key;
|
||||
tr_variant* child;
|
||||
while (tr_variantDictChild(const_cast<tr_variant*>(value), pos++, &key, &child))
|
||||
{
|
||||
switch (key)
|
||||
{
|
||||
#define HANDLE_KEY(key, field) case TR_KEY_ ## key: \
|
||||
changed = change(setme.field, child) || changed; break;
|
||||
|
||||
HANDLE_KEY(address, address)
|
||||
HANDLE_KEY(clientIsChoked, client_is_choked)
|
||||
HANDLE_KEY(clientIsInterested, client_is_interested)
|
||||
HANDLE_KEY(clientName, client_name)
|
||||
HANDLE_KEY(flagStr, flags)
|
||||
HANDLE_KEY(isDownloadingFrom, is_downloading_from)
|
||||
HANDLE_KEY(isEncrypted, is_encrypted)
|
||||
HANDLE_KEY(isIncoming, is_incoming)
|
||||
HANDLE_KEY(isUploadingTo, is_uploading_to)
|
||||
HANDLE_KEY(peerIsChoked, peer_is_choked)
|
||||
HANDLE_KEY(peerIsInterested, peer_is_interested)
|
||||
HANDLE_KEY(port, port)
|
||||
HANDLE_KEY(progress, progress)
|
||||
HANDLE_KEY(rateToClient, rate_to_client)
|
||||
HANDLE_KEY(rateToPeer, rate_to_peer)
|
||||
#undef HANDLE_KEY
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
bool change(TorrentFile& setme, tr_variant const* value)
|
||||
{
|
||||
bool changed = false;
|
||||
|
||||
size_t pos = 0;
|
||||
tr_quark key;
|
||||
tr_variant* child;
|
||||
while (tr_variantDictChild(const_cast<tr_variant*>(value), pos++, &key, &child))
|
||||
{
|
||||
switch (key)
|
||||
{
|
||||
#define HANDLE_KEY(key) case TR_KEY_ ## key: \
|
||||
changed = change(setme.key, child) || changed; break;
|
||||
|
||||
HANDLE_KEY(have)
|
||||
HANDLE_KEY(priority)
|
||||
HANDLE_KEY(wanted)
|
||||
#undef HANDLE_KEY
|
||||
#define HANDLE_KEY(key, field) case TR_KEY_ ## key: \
|
||||
changed = change(setme.field, child) || changed; break;
|
||||
|
||||
HANDLE_KEY(bytesCompleted, have)
|
||||
HANDLE_KEY(length, size)
|
||||
HANDLE_KEY(name, filename)
|
||||
#undef HANDLE_KEY
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
bool change(TrackerStat& setme, tr_variant const* value)
|
||||
{
|
||||
bool changed = false;
|
||||
|
||||
size_t pos = 0;
|
||||
tr_quark key;
|
||||
tr_variant* child;
|
||||
while (tr_variantDictChild(const_cast<tr_variant*>(value), pos++, &key, &child))
|
||||
{
|
||||
bool field_changed = false;
|
||||
|
||||
switch (key)
|
||||
{
|
||||
#define HANDLE_KEY(key, field) case TR_KEY_ ## key: \
|
||||
field_changed = change(setme.field, child); break;
|
||||
HANDLE_KEY(announce, announce)
|
||||
HANDLE_KEY(announceState, announce_state)
|
||||
HANDLE_KEY(downloadCount, download_count)
|
||||
HANDLE_KEY(hasAnnounced, has_announced)
|
||||
HANDLE_KEY(hasScraped, has_scraped)
|
||||
HANDLE_KEY(host, host);
|
||||
HANDLE_KEY(id, id);
|
||||
HANDLE_KEY(isBackup, is_backup);
|
||||
HANDLE_KEY(lastAnnouncePeerCount, last_announce_peer_count);
|
||||
HANDLE_KEY(lastAnnounceResult, last_announce_result);
|
||||
HANDLE_KEY(lastAnnounceStartTime, last_announce_start_time)
|
||||
HANDLE_KEY(lastAnnounceSucceeded, last_announce_succeeded)
|
||||
HANDLE_KEY(lastAnnounceTime, last_announce_time)
|
||||
HANDLE_KEY(lastAnnounceTimedOut, last_announce_timed_out)
|
||||
HANDLE_KEY(lastScrapeResult, last_scrape_result)
|
||||
HANDLE_KEY(lastScrapeStartTime, last_scrape_start_time)
|
||||
HANDLE_KEY(lastScrapeSucceeded, last_scrape_succeeded)
|
||||
HANDLE_KEY(lastScrapeTime, last_scrape_time)
|
||||
HANDLE_KEY(lastScrapeTimedOut, last_scrape_timed_out)
|
||||
HANDLE_KEY(leecherCount, leecher_count)
|
||||
HANDLE_KEY(nextAnnounceTime, next_announce_time)
|
||||
HANDLE_KEY(nextScrapeTime, next_scrape_time)
|
||||
HANDLE_KEY(scrapeState, scrape_state)
|
||||
HANDLE_KEY(seederCount, seeder_count)
|
||||
HANDLE_KEY(tier, tier)
|
||||
|
||||
#undef HANDLE_KEY
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (field_changed)
|
||||
{
|
||||
if (key == TR_KEY_announce)
|
||||
{
|
||||
setme.favicon_key = qApp->faviconCache().add(QUrl(setme.announce));
|
||||
}
|
||||
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
///
|
||||
|
||||
void variantInit(tr_variant* init_me, bool value)
|
||||
{
|
||||
tr_variantInitBool(init_me, value);
|
||||
}
|
||||
|
||||
void variantInit(tr_variant* init_me, int64_t value)
|
||||
{
|
||||
tr_variantInitInt(init_me, value);
|
||||
}
|
||||
|
||||
void variantInit(tr_variant* init_me, int value)
|
||||
{
|
||||
tr_variantInitInt(init_me, value);
|
||||
}
|
||||
|
||||
void variantInit(tr_variant* init_me, unsigned int value)
|
||||
{
|
||||
tr_variantInitInt(init_me, value);
|
||||
}
|
||||
|
||||
void variantInit(tr_variant* init_me, double value)
|
||||
{
|
||||
tr_variantInitReal(init_me, value);
|
||||
}
|
||||
|
||||
void variantInit(tr_variant* init_me, QByteArray const& value)
|
||||
{
|
||||
tr_variantInitRaw(init_me, value.constData(), value.size());
|
||||
}
|
||||
|
||||
void variantInit(tr_variant* init_me, QString const& value)
|
||||
{
|
||||
variantInit(init_me, value.toUtf8());
|
||||
}
|
||||
|
||||
void variantInit(tr_variant* init_me, std::string_view value)
|
||||
{
|
||||
tr_variantInitStr(init_me, std::data(value), std::size(value));
|
||||
}
|
||||
|
||||
} // namespace trqt::variant_helpers
|
187
qt/VariantHelpers.h
Normal file
187
qt/VariantHelpers.h
Normal file
|
@ -0,0 +1,187 @@
|
|||
/*
|
||||
* This file Copyright (C) 2020 Mnemosyne LLC
|
||||
*
|
||||
* It may be used under the GNU GPL versions 2 or 3
|
||||
* or any future license endorsed by Mnemosyne LLC.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string_view>
|
||||
#include <optional>
|
||||
|
||||
#include <QString>
|
||||
#include <QVector>
|
||||
|
||||
#include <libtransmission/variant.h>
|
||||
|
||||
class QByteArray;
|
||||
|
||||
class Speed;
|
||||
struct Peer;
|
||||
struct TorrentFile;
|
||||
struct TrackerStat;
|
||||
|
||||
namespace trqt
|
||||
{
|
||||
|
||||
namespace variant_helpers
|
||||
{
|
||||
|
||||
template<typename T,
|
||||
typename std::enable_if<std::is_same_v<T, bool>>::type* = nullptr>
|
||||
auto getValue(tr_variant const* variant)
|
||||
{
|
||||
std::optional<T> ret;
|
||||
auto value = T {};
|
||||
if (tr_variantGetBool(variant, &value))
|
||||
{
|
||||
ret = value;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
template<typename T,
|
||||
typename std::enable_if<std::is_same_v<T, int64_t>||
|
||||
std::is_same_v<T, uint64_t>||
|
||||
std::is_same_v<T, int>||
|
||||
std::is_same_v<T, time_t>>::type* = nullptr>
|
||||
auto getValue(tr_variant const* variant)
|
||||
{
|
||||
std::optional<T> ret;
|
||||
auto value = int64_t {};
|
||||
if (tr_variantGetInt(variant, &value))
|
||||
{
|
||||
ret = value;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
template<typename T,
|
||||
typename std::enable_if<std::is_same_v<T, double>>::type* = nullptr>
|
||||
auto getValue(tr_variant const* variant)
|
||||
{
|
||||
std::optional<T> ret;
|
||||
auto value = T {};
|
||||
if (tr_variantGetReal(variant, &value))
|
||||
{
|
||||
ret = value;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
template<typename T, typename std::enable_if<std::is_same_v<T, QString>>::type* = nullptr>
|
||||
auto getValue(tr_variant const* variant)
|
||||
{
|
||||
std::optional<T> ret;
|
||||
char const* str;
|
||||
size_t len;
|
||||
if (tr_variantGetStr(variant, &str, &len))
|
||||
{
|
||||
ret = QString::fromUtf8(str, len);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool change(T& setme, T const& value)
|
||||
{
|
||||
bool const changed = setme != value;
|
||||
|
||||
if (changed)
|
||||
{
|
||||
setme = value;
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
bool change(double& setme, double const& value);
|
||||
bool change(Speed& setme, tr_variant const* value);
|
||||
bool change(Peer& setme, tr_variant const* value);
|
||||
bool change(TorrentFile& setme, tr_variant const* value);
|
||||
bool change(TrackerStat& setme, tr_variant const* value);
|
||||
|
||||
template<typename T>
|
||||
bool change(T& setme, tr_variant const* variant)
|
||||
{
|
||||
auto const value = getValue<T>(variant);
|
||||
return value && change(setme, *value);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool change(QVector<T>& setme, tr_variant const* value)
|
||||
{
|
||||
bool changed = false;
|
||||
|
||||
int const n = tr_variantListSize(value);
|
||||
if (setme.size() != n)
|
||||
{
|
||||
setme.resize(n);
|
||||
changed = true;
|
||||
}
|
||||
|
||||
for (int i = 0; i < n; ++i)
|
||||
{
|
||||
changed = change(setme[i], tr_variantListChild(const_cast<tr_variant*>(value), i)) || changed;
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
///
|
||||
|
||||
template<typename T>
|
||||
auto dictFind(tr_variant* dict, tr_quark key)
|
||||
{
|
||||
std::optional<T> ret;
|
||||
auto const* child = tr_variantDictFind(dict, key);
|
||||
if (child != nullptr)
|
||||
{
|
||||
ret = getValue<T>(child);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
///
|
||||
|
||||
void variantInit(tr_variant* init_me, bool value);
|
||||
void variantInit(tr_variant* init_me, int64_t value);
|
||||
void variantInit(tr_variant* init_me, int value);
|
||||
void variantInit(tr_variant* init_me, unsigned int value);
|
||||
void variantInit(tr_variant* init_me, double value);
|
||||
void variantInit(tr_variant* init_me, QByteArray const& value);
|
||||
void variantInit(tr_variant* init_me, QString const& value);
|
||||
void variantInit(tr_variant* init_me, std::string_view value);
|
||||
|
||||
template<typename C, typename T = typename C::value_type>
|
||||
void variantInit(tr_variant* init_me, C const& value)
|
||||
{
|
||||
tr_variantInitList(init_me, std::size(value));
|
||||
for (auto const& item : value)
|
||||
{
|
||||
variantInit(tr_variantListAdd(init_me), item);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void listAdd(tr_variant* list, T const& value)
|
||||
{
|
||||
variantInit(tr_variantListAdd(list), value);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void dictAdd(tr_variant* dict, tr_quark key, T const& value)
|
||||
{
|
||||
variantInit(tr_variantDictAdd(dict, key), value);
|
||||
}
|
||||
|
||||
} // namespace variant_helpers
|
||||
|
||||
} // trqt
|
|
@ -119,6 +119,7 @@ SOURCES += AboutDialog.cc \
|
|||
TrackerModel.cc \
|
||||
TrackerModelFilter.cc \
|
||||
Utils.cc \
|
||||
VariantHelpers.cc \
|
||||
WatchDir.cc
|
||||
HEADERS += $$replace(SOURCES, .cc, .h)
|
||||
HEADERS += BaseDialog.h CustomVariantType.h Speed.h Typedefs.h
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
|
||||
#define MY_NAME "transmission-remote"
|
||||
#define DEFAULT_HOST "localhost"
|
||||
#define DEFAULT_PORT atoi(TR_DEFAULT_RPC_PORT_STR)
|
||||
#define DEFAULT_PORT TR_DEFAULT_RPC_PORT
|
||||
#define DEFAULT_URL TR_DEFAULT_RPC_URL_STR "rpc/"
|
||||
|
||||
#define ARGUMENTS TR_KEY_arguments
|
||||
|
|
Loading…
Reference in a new issue