Compare commits
6 Commits
21c2b74318
...
29dc11c3d4
Author | SHA1 | Date |
---|---|---|
H5117 | 29dc11c3d4 | |
Pooyan Khanjankhani | 821a6816ef | |
Dzmitry Neviadomski | ef18816b7f | |
Dzmitry Neviadomski | 0e25584e78 | |
Dzmitry Neviadomski | bd0b74fccb | |
Vladimir Stoiakin | 17cb035a44 |
|
@ -41,7 +41,7 @@ On macOS, Transmission is usually built with Xcode. Everywhere else, it's CMake
|
|||
- Prefer `enum class` over `enum`
|
||||
- Prefer new-style headers, e.g. `<cstring>` over `<string.h>`
|
||||
- Fix any warnings in new code before merging
|
||||
- Run `./code-style.sh` on your code to ensure the whole codebase has consistent indentation.
|
||||
- Run `./code_style.sh` on your code to ensure the whole codebase has consistent indentation.
|
||||
|
||||
Note that Transmission existed in C for over a decade and those idioms don't change overnight. "Follow the C++ core guidelines" can be difficult when working with older code, and the maintainers will understand that when reviewing your PRs. :smiley:
|
||||
|
||||
|
|
|
@ -404,7 +404,7 @@ struct tr_socket_address
|
|||
};
|
||||
|
||||
template<>
|
||||
class std::hash<tr_socket_address>
|
||||
struct std::hash<tr_socket_address>
|
||||
{
|
||||
public:
|
||||
std::size_t operator()(tr_socket_address const& socket_address) const noexcept
|
||||
|
|
|
@ -74,7 +74,7 @@ auto constexpr TrUnixSocketPrefix = "unix:"sv;
|
|||
#ifdef _WIN32
|
||||
auto inline constexpr TrUnixAddrStrLen = size_t{ INET6_ADDRSTRLEN };
|
||||
#else
|
||||
auto inline constexpr TrUnixAddrStrLen = size_t{ sizeof(((struct sockaddr_un*)nullptr)->sun_path) +
|
||||
auto inline constexpr TrUnixAddrStrLen = size_t{ sizeof(std::declval<struct sockaddr_un>().sun_path) +
|
||||
std::size(TrUnixSocketPrefix) };
|
||||
#endif
|
||||
|
||||
|
|
|
@ -46,9 +46,22 @@
|
|||
#include "TorrentModel.h"
|
||||
#include "WatchDir.h"
|
||||
|
||||
#define APP_DISPLAY_NAME "transmission-qt"
|
||||
#define APP_CONFIG_NAME "transmission"
|
||||
|
||||
#ifdef QT_DBUS_LIB
|
||||
#define FDO_NOTIFICATIONS_SERVICE_NAME "org.freedesktop.Notifications"
|
||||
#define FDO_NOTIFICATIONS_PATH "/org/freedesktop/Notifications"
|
||||
#define FDO_NOTIFICATIONS_INTERFACE_NAME "org.freedesktop.Notifications"
|
||||
#endif
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
auto constexpr StatsRefreshIntervalMsec = 3000;
|
||||
auto constexpr SessionRefreshIntervalMsec = 3000;
|
||||
auto constexpr ModelRefreshIntervalMsec = 3000;
|
||||
|
||||
std::array<tr_option, 8> const Opts = {
|
||||
tr_option{ 'g', "config-dir", "Where to look for configuration files", "g", true, "<path>" },
|
||||
{ 'm', "minimized", "Start minimized in system tray", "m", false, nullptr },
|
||||
|
@ -66,10 +79,6 @@ char const* getUsage()
|
|||
" transmission [OPTIONS...] [torrent files]";
|
||||
}
|
||||
|
||||
auto constexpr StatsRefreshIntervalMsec = 3000;
|
||||
auto constexpr SessionRefreshIntervalMsec = 3000;
|
||||
auto constexpr ModelRefreshIntervalMsec = 3000;
|
||||
|
||||
bool loadTranslation(QTranslator& translator, QString const& name, QLocale const& locale, QStringList const& search_directories)
|
||||
{
|
||||
for (QString const& directory : search_directories)
|
||||
|
@ -83,7 +92,33 @@ bool loadTranslation(QTranslator& translator, QString const& name, QLocale const
|
|||
return false;
|
||||
}
|
||||
|
||||
[[nodiscard]] auto makeWindowIcon()
|
||||
void initUnits()
|
||||
{
|
||||
using Config = libtransmission::Values::Config;
|
||||
|
||||
Config::Speed = { Config::Base::Kilo,
|
||||
QObject::tr("B/s").toStdString(),
|
||||
QObject::tr("kB/s").toStdString(),
|
||||
QObject::tr("MB/s").toStdString(),
|
||||
QObject::tr("GB/s").toStdString(),
|
||||
QObject::tr("TB/s").toStdString() };
|
||||
|
||||
Config::Memory = { Config::Base::Kibi,
|
||||
QObject::tr("B").toStdString(),
|
||||
QObject::tr("KiB").toStdString(),
|
||||
QObject::tr("MiB").toStdString(),
|
||||
QObject::tr("GiB").toStdString(),
|
||||
QObject::tr("TiB").toStdString() };
|
||||
|
||||
Config::Storage = { Config::Base::Kilo,
|
||||
QObject::tr("B").toStdString(),
|
||||
QObject::tr("kB").toStdString(),
|
||||
QObject::tr("MB").toStdString(),
|
||||
QObject::tr("GB").toStdString(),
|
||||
QObject::tr("TB").toStdString() };
|
||||
}
|
||||
|
||||
auto makeWindowIcon()
|
||||
{
|
||||
// first, try to load it from the system theme
|
||||
if (auto icon = QIcon::fromTheme(QStringLiteral("transmission")); !icon.isNull())
|
||||
|
@ -116,12 +151,11 @@ QAccessibleInterface* accessibleFactory(QString const& className, QObject* objec
|
|||
|
||||
} // namespace
|
||||
|
||||
Application::Application(int& argc, char** argv)
|
||||
Application::Application(int argc, char** argv, int& exit_code)
|
||||
: QApplication{ argc, argv }
|
||||
, config_name_{ QStringLiteral("transmission") }
|
||||
, display_name_{ QStringLiteral("transmission-qt") }
|
||||
{
|
||||
setApplicationName(config_name_);
|
||||
{
|
||||
setApplicationName(QStringLiteral(APP_CONFIG_NAME));
|
||||
loadTranslations();
|
||||
initUnits();
|
||||
|
||||
|
@ -140,10 +174,10 @@ Application::Application(int& argc, char** argv)
|
|||
setAttribute(Qt::AA_DontShowIconsInMenus);
|
||||
#endif
|
||||
|
||||
tr_locale_set_global("");
|
||||
|
||||
// parse the command-line arguments
|
||||
int c = 0;
|
||||
bool minimized = false;
|
||||
char const* optarg = nullptr;
|
||||
QString host;
|
||||
QString port;
|
||||
QString username;
|
||||
|
@ -151,6 +185,8 @@ Application::Application(int& argc, char** argv)
|
|||
QString config_dir;
|
||||
QStringList filenames;
|
||||
|
||||
int c = 0;
|
||||
char const* optarg = nullptr;
|
||||
while ((c = tr_getopt(getUsage(), argc, const_cast<char const**>(argv), Opts.data(), &optarg)) != TR_OPT_DONE)
|
||||
{
|
||||
switch (c)
|
||||
|
@ -180,14 +216,13 @@ Application::Application(int& argc, char** argv)
|
|||
break;
|
||||
|
||||
case 'v':
|
||||
qInfo() << qPrintable(display_name_) << LONG_VERSION_STRING;
|
||||
quitLater();
|
||||
qInfo() << APP_DISPLAY_NAME << LONG_VERSION_STRING;
|
||||
return;
|
||||
|
||||
case TR_OPT_ERR:
|
||||
qWarning() << qPrintable(QObject::tr("Invalid option"));
|
||||
tr_getopt_usage(qPrintable(display_name_), getUsage(), Opts.data());
|
||||
quitLater();
|
||||
qWarning() << qUtf8Printable(QObject::tr("Invalid option"));
|
||||
tr_getopt_usage(APP_DISPLAY_NAME, getUsage(), Opts.data());
|
||||
exit_code = 1;
|
||||
return;
|
||||
|
||||
default:
|
||||
|
@ -198,6 +233,7 @@ Application::Application(int& argc, char** argv)
|
|||
|
||||
// try to delegate the work to an existing copy of Transmission
|
||||
// before starting ourselves...
|
||||
InteropHelper::initialize();
|
||||
InteropHelper const interop_client;
|
||||
|
||||
if (interop_client.isConnected())
|
||||
|
@ -236,7 +272,6 @@ Application::Application(int& argc, char** argv)
|
|||
|
||||
if (delegated)
|
||||
{
|
||||
quitLater();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -315,7 +350,11 @@ Application::Application(int& argc, char** argv)
|
|||
connect(session_.get(), &Session::sourceChanged, this, &Application::onSessionSourceChanged);
|
||||
connect(session_.get(), &Session::torrentsRemoved, model_.get(), &TorrentModel::removeTorrents);
|
||||
connect(session_.get(), &Session::torrentsUpdated, model_.get(), &TorrentModel::updateTorrents);
|
||||
connect(watch_dir_.get(), &WatchDir::torrentFileAdded, this, qOverload<QString const&>(&Application::addWatchdirTorrent));
|
||||
connect(
|
||||
watch_dir_.get(),
|
||||
&WatchDir::torrentFileAdded,
|
||||
this,
|
||||
qOverload<QString const&>(&Application::addWatchdirTorrent));
|
||||
|
||||
// init from preferences
|
||||
for (auto const key : { Prefs::DIR_WATCH })
|
||||
|
@ -384,9 +423,9 @@ Application::Application(int& argc, char** argv)
|
|||
if (auto bus = QDBusConnection::sessionBus(); bus.isConnected())
|
||||
{
|
||||
bus.connect(
|
||||
fdo_notifications_service_name_,
|
||||
fdo_notifications_path_,
|
||||
fdo_notifications_interface_name_,
|
||||
QStringLiteral(FDO_NOTIFICATIONS_SERVICE_NAME),
|
||||
QStringLiteral(FDO_NOTIFICATIONS_PATH),
|
||||
QStringLiteral(FDO_NOTIFICATIONS_INTERFACE_NAME),
|
||||
QLatin1String("ActionInvoked"),
|
||||
this,
|
||||
SLOT(onNotificationActionInvoked(quint32, QString)));
|
||||
|
@ -395,6 +434,9 @@ Application::Application(int& argc, char** argv)
|
|||
#endif
|
||||
}
|
||||
|
||||
exit_code = exec();
|
||||
}
|
||||
|
||||
void Application::loadTranslations()
|
||||
{
|
||||
auto const qt_qm_dirs = QStringList{} <<
|
||||
|
@ -425,32 +467,13 @@ void Application::loadTranslations()
|
|||
installTranslator(&qt_translator_);
|
||||
}
|
||||
|
||||
if (loadTranslation(app_translator_, config_name_, locale, app_qm_dirs) ||
|
||||
loadTranslation(app_translator_, config_name_, english_locale, app_qm_dirs))
|
||||
if (loadTranslation(app_translator_, QStringLiteral(APP_CONFIG_NAME), locale, app_qm_dirs) ||
|
||||
loadTranslation(app_translator_, QStringLiteral(APP_CONFIG_NAME), english_locale, app_qm_dirs))
|
||||
{
|
||||
installTranslator(&app_translator_);
|
||||
}
|
||||
}
|
||||
|
||||
void Application::initUnits()
|
||||
{
|
||||
using Config = libtransmission::Values::Config;
|
||||
|
||||
Config::Speed = { Config::Base::Kilo, tr("B/s").toStdString(), tr("kB/s").toStdString(),
|
||||
tr("MB/s").toStdString(), tr("GB/s").toStdString(), tr("TB/s").toStdString() };
|
||||
|
||||
Config::Memory = { Config::Base::Kibi, tr("B").toStdString(), tr("KiB").toStdString(),
|
||||
tr("MiB").toStdString(), tr("GiB").toStdString(), tr("TiB").toStdString() };
|
||||
|
||||
Config::Storage = { Config::Base::Kilo, tr("B").toStdString(), tr("kB").toStdString(),
|
||||
tr("MB").toStdString(), tr("GB").toStdString(), tr("TB").toStdString() };
|
||||
}
|
||||
|
||||
void Application::quitLater() const
|
||||
{
|
||||
QTimer::singleShot(0, this, SLOT(quit()));
|
||||
}
|
||||
|
||||
void Application::onTorrentsEdited(torrent_ids_t const& torrent_ids) const
|
||||
{
|
||||
// the backend's tr_info has changed, so reload those fields
|
||||
|
@ -666,9 +689,9 @@ bool Application::notifyApp(QString const& title, QString const& body, QStringLi
|
|||
if (auto bus = QDBusConnection::sessionBus(); bus.isConnected())
|
||||
{
|
||||
QDBusMessage m = QDBusMessage::createMethodCall(
|
||||
fdo_notifications_service_name_,
|
||||
fdo_notifications_path_,
|
||||
fdo_notifications_interface_name_,
|
||||
QStringLiteral(FDO_NOTIFICATIONS_SERVICE_NAME),
|
||||
QStringLiteral(FDO_NOTIFICATIONS_PATH),
|
||||
QStringLiteral(FDO_NOTIFICATIONS_INTERFACE_NAME),
|
||||
QStringLiteral("Notify"));
|
||||
QVariantList args;
|
||||
args.append(QStringLiteral("Transmission")); // app_name
|
||||
|
@ -699,7 +722,9 @@ bool Application::notifyApp(QString const& title, QString const& body, QStringLi
|
|||
#ifdef QT_DBUS_LIB
|
||||
void Application::onNotificationActionInvoked(quint32 /* notification_id */, QString action_key)
|
||||
{
|
||||
auto const match = start_now_regex_.match(action_key);
|
||||
static const QRegularExpression start_now_regex{ QStringLiteral(R"rgx(start-now\((\d+)\))rgx") };
|
||||
|
||||
auto const match = start_now_regex.match(action_key);
|
||||
if (match.hasMatch())
|
||||
{
|
||||
int const torrent_id = match.captured(1).toInt();
|
||||
|
@ -716,10 +741,7 @@ int tr_main(int argc, char** argv)
|
|||
{
|
||||
auto const init_mgr = tr_lib_init();
|
||||
|
||||
tr_locale_set_global("");
|
||||
|
||||
InteropHelper::initialize();
|
||||
|
||||
Application const app(argc, argv);
|
||||
return QApplication::exec();
|
||||
int exit_code = 0;
|
||||
Application const app(argc, argv, exit_code);
|
||||
return exit_code;
|
||||
}
|
||||
|
|
|
@ -10,6 +10,8 @@
|
|||
#include <unordered_set>
|
||||
|
||||
#include <QApplication>
|
||||
#include <QPixmap>
|
||||
#include <QPointer>
|
||||
#include <QRegularExpression>
|
||||
#include <QTimer>
|
||||
#include <QTranslator>
|
||||
|
@ -20,7 +22,6 @@
|
|||
|
||||
#include "AddData.h"
|
||||
#include "Typedefs.h"
|
||||
#include "Utils.h" // std::hash<QString>
|
||||
|
||||
class AddData;
|
||||
class MainWindow;
|
||||
|
@ -36,7 +37,7 @@ class Application : public QApplication
|
|||
TR_DISABLE_COPY_MOVE(Application)
|
||||
|
||||
public:
|
||||
Application(int& argc, char** argv);
|
||||
Application(int argc, char** argv, int& exit_code);
|
||||
|
||||
void raise() const;
|
||||
bool notifyApp(QString const& title, QString const& body, QStringList const& actions = {}) const;
|
||||
|
@ -92,9 +93,7 @@ private slots:
|
|||
private:
|
||||
void maybeUpdateBlocklist() const;
|
||||
void loadTranslations();
|
||||
void initUnits();
|
||||
QStringList getNames(torrent_ids_t const& ids) const;
|
||||
void quitLater() const;
|
||||
void notifyTorrentAdded(Torrent const*) const;
|
||||
|
||||
std::unordered_set<QString> interned_strings_;
|
||||
|
@ -112,17 +111,6 @@ private:
|
|||
QTranslator app_translator_;
|
||||
|
||||
FaviconCache<QPixmap> favicon_cache_;
|
||||
|
||||
QString const config_name_ = QStringLiteral("transmission");
|
||||
QString const display_name_ = QStringLiteral("transmission-qt");
|
||||
|
||||
#ifdef QT_DBUS_LIB
|
||||
QString const fdo_notifications_service_name_ = QStringLiteral("org.freedesktop.Notifications");
|
||||
QString const fdo_notifications_path_ = QStringLiteral("/org/freedesktop/Notifications");
|
||||
QString const fdo_notifications_interface_name_ = QStringLiteral("org.freedesktop.Notifications");
|
||||
#endif
|
||||
|
||||
QRegularExpression const start_now_regex_{ QStringLiteral(R"rgx(start-now\((\d+)\))rgx") };
|
||||
};
|
||||
|
||||
#define trApp dynamic_cast<Application*>(Application::instance())
|
||||
|
|
|
@ -150,7 +150,7 @@ Get a file list for the current torrent(s)
|
|||
.It Fl g Fl -get Ar all | file-index | files
|
||||
Mark file(s) for download.
|
||||
.Ar all
|
||||
marks all all of the torrent's files for downloading,
|
||||
marks all of the torrent's files for downloading,
|
||||
.Ar file-index
|
||||
adds a single file to the download list, and
|
||||
.Ar files
|
||||
|
|
Loading…
Reference in New Issue