diff --git a/src/base/bittorrent/torrenthandle.h b/src/base/bittorrent/torrenthandle.h index 7fea30c55..1fe9594d7 100644 --- a/src/base/bittorrent/torrenthandle.h +++ b/src/base/bittorrent/torrenthandle.h @@ -238,6 +238,9 @@ namespace BitTorrent virtual int downloadLimit() const = 0; virtual int uploadLimit() const = 0; virtual bool superSeeding() const = 0; + virtual bool isDHTDisabled() const = 0; + virtual bool isPEXDisabled() const = 0; + virtual bool isLSDDisabled() const = 0; virtual QVector peers() const = 0; virtual QBitArray pieces() const = 0; virtual QBitArray downloadingPieces() const = 0; @@ -277,6 +280,9 @@ namespace BitTorrent virtual void setUploadLimit(int limit) = 0; virtual void setDownloadLimit(int limit) = 0; virtual void setSuperSeeding(bool enable) = 0; + virtual void setDHTDisabled(bool disable) = 0; + virtual void setPEXDisabled(bool disable) = 0; + virtual void setLSDDisabled(bool disable) = 0; virtual void flushCache() const = 0; virtual void addTrackers(const QVector &trackers) = 0; virtual void replaceTrackers(const QVector &trackers) = 0; diff --git a/src/base/bittorrent/torrenthandleimpl.cpp b/src/base/bittorrent/torrenthandleimpl.cpp index 2424e5f16..071efa60e 100644 --- a/src/base/bittorrent/torrenthandleimpl.cpp +++ b/src/base/bittorrent/torrenthandleimpl.cpp @@ -1016,6 +1016,21 @@ bool TorrentHandleImpl::superSeeding() const return static_cast(m_nativeStatus.flags & lt::torrent_flags::super_seeding); } +bool TorrentHandleImpl::isDHTDisabled() const +{ + return static_cast(m_nativeStatus.flags & lt::torrent_flags::disable_dht); +} + +bool TorrentHandleImpl::isPEXDisabled() const +{ + return static_cast(m_nativeStatus.flags & lt::torrent_flags::disable_pex); +} + +bool TorrentHandleImpl::isLSDDisabled() const +{ + return static_cast(m_nativeStatus.flags & lt::torrent_flags::disable_lsd); +} + QVector TorrentHandleImpl::peers() const { std::vector nativePeers; @@ -1935,20 +1950,68 @@ void TorrentHandleImpl::setSeedingTimeLimit(int limit) void TorrentHandleImpl::setUploadLimit(const int limit) { + if (limit == uploadLimit()) + return; + m_nativeHandle.set_upload_limit(limit); + saveResumeData(); } void TorrentHandleImpl::setDownloadLimit(const int limit) { + if (limit == downloadLimit()) + return; + m_nativeHandle.set_download_limit(limit); + saveResumeData(); } void TorrentHandleImpl::setSuperSeeding(const bool enable) { + if (enable == superSeeding()) + return; + if (enable) m_nativeHandle.set_flags(lt::torrent_flags::super_seeding); else m_nativeHandle.unset_flags(lt::torrent_flags::super_seeding); + saveResumeData(); +} + +void TorrentHandleImpl::setDHTDisabled(const bool disable) +{ + if (disable == isDHTDisabled()) + return; + + if (disable) + m_nativeHandle.set_flags(lt::torrent_flags::disable_dht); + else + m_nativeHandle.unset_flags(lt::torrent_flags::disable_dht); + saveResumeData(); +} + +void TorrentHandleImpl::setPEXDisabled(const bool disable) +{ + if (disable == isPEXDisabled()) + return; + + if (disable) + m_nativeHandle.set_flags(lt::torrent_flags::disable_pex); + else + m_nativeHandle.unset_flags(lt::torrent_flags::disable_pex); + saveResumeData(); +} + +void TorrentHandleImpl::setLSDDisabled(const bool disable) +{ + if (disable == isLSDDisabled()) + return; + + if (disable) + m_nativeHandle.set_flags(lt::torrent_flags::disable_lsd); + else + m_nativeHandle.unset_flags(lt::torrent_flags::disable_lsd); + saveResumeData(); } void TorrentHandleImpl::flushCache() const diff --git a/src/base/bittorrent/torrenthandleimpl.h b/src/base/bittorrent/torrenthandleimpl.h index 314dbbd19..a8f8c3f6c 100644 --- a/src/base/bittorrent/torrenthandleimpl.h +++ b/src/base/bittorrent/torrenthandleimpl.h @@ -191,6 +191,9 @@ namespace BitTorrent int downloadLimit() const override; int uploadLimit() const override; bool superSeeding() const override; + bool isDHTDisabled() const override; + bool isPEXDisabled() const override; + bool isLSDDisabled() const override; QVector peers() const override; QBitArray pieces() const override; QBitArray downloadingPieces() const override; @@ -224,6 +227,9 @@ namespace BitTorrent void setUploadLimit(int limit) override; void setDownloadLimit(int limit) override; void setSuperSeeding(bool enable) override; + void setDHTDisabled(bool disable) override; + void setPEXDisabled(bool disable) override; + void setLSDDisabled(bool disable) override; void flushCache() const override; void addTrackers(const QVector &trackers) override; void replaceTrackers(const QVector &trackers) override; diff --git a/src/base/unicodestrings.h b/src/base/unicodestrings.h index 493890c86..e855fe9d5 100644 --- a/src/base/unicodestrings.h +++ b/src/base/unicodestrings.h @@ -38,6 +38,7 @@ // See issue #3059 for more details (https://github.com/qbittorrent/qBittorrent/issues/3059). const char C_COPYRIGHT[] = "©"; +const char C_INEQUALITY[] = "≠"; const char C_INFINITY[] = "∞"; const char C_NON_BREAKING_SPACE[] = " "; const char C_THIN_SPACE[] = " "; diff --git a/src/gui/CMakeLists.txt b/src/gui/CMakeLists.txt index 1169cb51d..bafec9458 100644 --- a/src/gui/CMakeLists.txt +++ b/src/gui/CMakeLists.txt @@ -67,6 +67,7 @@ add_library(qbt_gui STATIC torrentcontentmodelitem.h torrentcontenttreeview.h torrentcreatordialog.h + torrentoptionsdialog.h trackerentriesdialog.h transferlistdelegate.h transferlistfilterswidget.h @@ -76,7 +77,6 @@ add_library(qbt_gui STATIC tristateaction.h tristatewidget.h uithememanager.h - updownratiodialog.h utils.h # sources @@ -147,6 +147,7 @@ add_library(qbt_gui STATIC torrentcontentmodelitem.cpp torrentcontenttreeview.cpp torrentcreatordialog.cpp + torrentoptionsdialog.cpp trackerentriesdialog.cpp transferlistdelegate.cpp transferlistfilterswidget.cpp @@ -156,7 +157,6 @@ add_library(qbt_gui STATIC tristateaction.cpp tristatewidget.cpp uithememanager.cpp - updownratiodialog.cpp utils.cpp # forms @@ -186,8 +186,8 @@ add_library(qbt_gui STATIC statsdialog.ui torrentcategorydialog.ui torrentcreatordialog.ui + torrentoptionsdialog.ui trackerentriesdialog.ui - updownratiodialog.ui ) target_sources(qbt_gui INTERFACE about.qrc) diff --git a/src/gui/gui.pri b/src/gui/gui.pri index aa33bacc1..5f2ecec09 100644 --- a/src/gui/gui.pri +++ b/src/gui/gui.pri @@ -68,6 +68,7 @@ HEADERS += \ $$PWD/torrentcontentmodelitem.h \ $$PWD/torrentcontenttreeview.h \ $$PWD/torrentcreatordialog.h \ + $$PWD/torrentoptionsdialog.h \ $$PWD/trackerentriesdialog.h \ $$PWD/transferlistdelegate.h \ $$PWD/transferlistfilterswidget.h \ @@ -77,7 +78,6 @@ HEADERS += \ $$PWD/tristateaction.h \ $$PWD/tristatewidget.h \ $$PWD/uithememanager.h \ - $$PWD/updownratiodialog.h \ $$PWD/utils.h SOURCES += \ @@ -148,6 +148,7 @@ SOURCES += \ $$PWD/torrentcontentmodelitem.cpp \ $$PWD/torrentcontenttreeview.cpp \ $$PWD/torrentcreatordialog.cpp \ + $$PWD/torrentoptionsdialog.cpp \ $$PWD/trackerentriesdialog.cpp \ $$PWD/transferlistdelegate.cpp \ $$PWD/transferlistfilterswidget.cpp \ @@ -157,7 +158,6 @@ SOURCES += \ $$PWD/tristateaction.cpp \ $$PWD/tristatewidget.cpp \ $$PWD/uithememanager.cpp \ - $$PWD/updownratiodialog.cpp \ $$PWD/utils.cpp win32|macx { @@ -207,7 +207,7 @@ FORMS += \ $$PWD/statsdialog.ui \ $$PWD/torrentcategorydialog.ui \ $$PWD/torrentcreatordialog.ui \ - $$PWD/trackerentriesdialog.ui \ - $$PWD/updownratiodialog.ui + $$PWD/torrentoptionsdialog.ui \ + $$PWD/trackerentriesdialog.ui RESOURCES += $$PWD/about.qrc diff --git a/src/gui/mainwindow.cpp b/src/gui/mainwindow.cpp index 0b777301f..d7ab5332d 100644 --- a/src/gui/mainwindow.cpp +++ b/src/gui/mainwindow.cpp @@ -172,10 +172,7 @@ MainWindow::MainWindow(QWidget *parent) m_ui->actionOpen->setIcon(UIThemeManager::instance()->getIcon("list-add")); m_ui->actionDownloadFromURL->setIcon(UIThemeManager::instance()->getIcon("insert-link")); - m_ui->actionSetUploadLimit->setIcon(UIThemeManager::instance()->getIcon("kt-set-max-upload-speed")); - m_ui->actionSetDownloadLimit->setIcon(UIThemeManager::instance()->getIcon("kt-set-max-download-speed")); - m_ui->actionSetGlobalUploadLimit->setIcon(UIThemeManager::instance()->getIcon("kt-set-max-upload-speed")); - m_ui->actionSetGlobalDownloadLimit->setIcon(UIThemeManager::instance()->getIcon("kt-set-max-download-speed")); + m_ui->actionSetGlobalSpeedLimits->setIcon(UIThemeManager::instance()->getIcon("speedometer")); m_ui->actionCreateTorrent->setIcon(UIThemeManager::instance()->getIcon("document-edit")); m_ui->actionAbout->setIcon(UIThemeManager::instance()->getIcon("help-about")); m_ui->actionStatistics->setIcon(UIThemeManager::instance()->getIcon("view-statistics")); @@ -1008,36 +1005,11 @@ void MainWindow::handleDownloadFromUrlFailure(const QString &url, const QString , tr("Couldn't download file at URL '%1', reason: %2.").arg(url, reason)); } -void MainWindow::on_actionSetGlobalUploadLimit_triggered() +void MainWindow::on_actionSetGlobalSpeedLimits_triggered() { - qDebug() << Q_FUNC_INFO; - - BitTorrent::Session *const session = BitTorrent::Session::instance(); - bool ok = false; - const long newLimit = SpeedLimitDialog::askSpeedLimit( - this, &ok, tr("Global Upload Speed Limit"), session->uploadSpeedLimit()); - - if (ok) - { - qDebug("Setting global upload rate limit to %.1fKb/s", newLimit / 1024.); - session->setUploadSpeedLimit(newLimit); - } -} - -void MainWindow::on_actionSetGlobalDownloadLimit_triggered() -{ - qDebug() << Q_FUNC_INFO; - - BitTorrent::Session *const session = BitTorrent::Session::instance(); - bool ok = false; - const long newLimit = SpeedLimitDialog::askSpeedLimit( - this, &ok, tr("Global Download Speed Limit"), session->downloadSpeedLimit()); - - if (ok) - { - qDebug("Setting global download rate limit to %.1fKb/s", newLimit / 1024.); - session->setDownloadSpeedLimit(newLimit); - } + auto dialog = new SpeedLimitDialog {this}; + dialog->setAttribute(Qt::WA_DeleteOnClose); + dialog->open(); } // Necessary if we want to close the window @@ -1808,8 +1780,7 @@ QMenu *MainWindow::trayIconMenu() updateAltSpeedsBtn(isAltBWEnabled); m_ui->actionUseAlternativeSpeedLimits->setChecked(isAltBWEnabled); m_trayIconMenu->addAction(m_ui->actionUseAlternativeSpeedLimits); - m_trayIconMenu->addAction(m_ui->actionSetGlobalDownloadLimit); - m_trayIconMenu->addAction(m_ui->actionSetGlobalUploadLimit); + m_trayIconMenu->addAction(m_ui->actionSetGlobalSpeedLimits); m_trayIconMenu->addSeparator(); m_trayIconMenu->addAction(m_ui->actionStartAll); m_trayIconMenu->addAction(m_ui->actionPauseAll); diff --git a/src/gui/mainwindow.h b/src/gui/mainwindow.h index b646a6e17..41c852918 100644 --- a/src/gui/mainwindow.h +++ b/src/gui/mainwindow.h @@ -171,8 +171,7 @@ private slots: void on_actionStatistics_triggered(); void on_actionCreateTorrent_triggered(); void on_actionOptions_triggered(); - void on_actionSetGlobalUploadLimit_triggered(); - void on_actionSetGlobalDownloadLimit_triggered(); + void on_actionSetGlobalSpeedLimits_triggered(); void on_actionDocumentation_triggered() const; void on_actionOpen_triggered(); void on_actionDownloadFromURL_triggered(); diff --git a/src/gui/mainwindow.ui b/src/gui/mainwindow.ui index d59b1e689..12cfc3eee 100644 --- a/src/gui/mainwindow.ui +++ b/src/gui/mainwindow.ui @@ -223,29 +223,14 @@ Torrent &Creator - - - Set Upload Limit... - - - - - Set Download Limit... - - &Documentation - - - Set Global Download Limit... - - - + - Set Global Upload Limit... + Set Global Speed Limits... diff --git a/src/gui/optionsdialog.ui b/src/gui/optionsdialog.ui index 47ac147eb..f27359d15 100644 --- a/src/gui/optionsdialog.ui +++ b/src/gui/optionsdialog.ui @@ -1902,7 +1902,7 @@ Manual: Various torrent properties (e.g. save path) must be assigned manually KiB/s - 1000000 + 2000000 100 @@ -1918,7 +1918,7 @@ Manual: Various torrent properties (e.g. save path) must be assigned manually KiB/s - 1000000 + 2000000 100 @@ -1973,7 +1973,7 @@ Manual: Various torrent properties (e.g. save path) must be assigned manually KiB/s - 1000000 + 2000000 10 @@ -2109,7 +2109,7 @@ Manual: Various torrent properties (e.g. save path) must be assigned manually KiB/s - 1000000 + 2000000 10 diff --git a/src/gui/properties/trackerlistwidget.cpp b/src/gui/properties/trackerlistwidget.cpp index ea33606c4..ce0193b5c 100644 --- a/src/gui/properties/trackerlistwidget.cpp +++ b/src/gui/properties/trackerlistwidget.cpp @@ -283,26 +283,34 @@ void TrackerListWidget::clear() void TrackerListWidget::loadStickyItems(const BitTorrent::TorrentHandle *torrent) { - QString working = tr("Working"); - QString disabled = tr("Disabled"); + const QString working {tr("Working")}; + const QString disabled {tr("Disabled")}; + const QString torrentDisabled {tr("Disabled for this torrent")}; + const auto *session = BitTorrent::Session::instance(); // load DHT information - if (BitTorrent::Session::instance()->isDHTEnabled() && !torrent->isPrivate()) - m_DHTItem->setText(COL_STATUS, working); - else + if (torrent->isPrivate() || torrent->isDHTDisabled()) + m_DHTItem->setText(COL_STATUS, torrentDisabled); + else if (!session->isDHTEnabled()) m_DHTItem->setText(COL_STATUS, disabled); + else + m_DHTItem->setText(COL_STATUS, working); // Load PeX Information - if (BitTorrent::Session::instance()->isPeXEnabled() && !torrent->isPrivate()) - m_PEXItem->setText(COL_STATUS, working); - else + if (torrent->isPrivate() || torrent->isPEXDisabled()) + m_PEXItem->setText(COL_STATUS, torrentDisabled); + else if (!session->isPeXEnabled()) m_PEXItem->setText(COL_STATUS, disabled); + else + m_PEXItem->setText(COL_STATUS, working); // Load LSD Information - if (BitTorrent::Session::instance()->isLSDEnabled() && !torrent->isPrivate()) - m_LSDItem->setText(COL_STATUS, working); - else + if (torrent->isPrivate() || torrent->isLSDDisabled()) + m_LSDItem->setText(COL_STATUS, torrentDisabled); + else if (!session->isLSDEnabled()) m_LSDItem->setText(COL_STATUS, disabled); + else + m_LSDItem->setText(COL_STATUS, working); if (torrent->isPrivate()) { diff --git a/src/gui/speedlimitdialog.cpp b/src/gui/speedlimitdialog.cpp index 59058eca9..334dd75ac 100644 --- a/src/gui/speedlimitdialog.cpp +++ b/src/gui/speedlimitdialog.cpp @@ -28,80 +28,107 @@ #include "speedlimitdialog.h" +#include + +#include "base/bittorrent/session.h" #include "ui_speedlimitdialog.h" +#include "uithememanager.h" #include "utils.h" -SpeedLimitDialog::SpeedLimitDialog(QWidget *parent) - : QDialog(parent) - , m_ui(new Ui::SpeedLimitDialog) +namespace { - m_ui->setupUi(this); - - // Connect to slots - connect(m_ui->bandwidthSlider, &QSlider::valueChanged, this, &SpeedLimitDialog::updateSpinValue); - connect(m_ui->spinBandwidth, qOverload(&QSpinBox::valueChanged) - , this, &SpeedLimitDialog::updateSliderValue); - - Utils::Gui::resize(this); -} - -SpeedLimitDialog::~SpeedLimitDialog() -{ - delete m_ui; + void updateSliderValue(QSlider *slider, const int value) + { + if (value > slider->maximum()) + slider->setMaximum(value); + slider->setValue(value); + } } -// -2: if cancel -long SpeedLimitDialog::askSpeedLimit(QWidget *parent, bool *ok, const QString &title, const long defaultVal, const long maxVal) +SpeedLimitDialog::SpeedLimitDialog(QWidget *parent) + : QDialog {parent} + , m_ui {new Ui::SpeedLimitDialog} { - if (ok) *ok = false; + m_ui->setupUi(this); - SpeedLimitDialog dlg(parent); - dlg.setWindowTitle(title); - dlg.setupDialog((maxVal / 1024.), (defaultVal / 1024.)); + m_ui->labelGlobalSpeedIcon->setPixmap(Utils::Gui::scaledPixmap(UIThemeManager::instance()->getIcon(QLatin1String("slow_off")) + , this, style()->pixelMetric(QStyle::PM_SmallIconSize, nullptr, this))); + m_ui->labelAltGlobalSpeedIcon->setPixmap(Utils::Gui::scaledPixmap(UIThemeManager::instance()->getIcon(QLatin1String("slow")) + , this, style()->pixelMetric(QStyle::PM_SmallIconSize, nullptr, this))); - if (dlg.exec() == QDialog::Accepted) + const auto initSlider = [](QSlider *slider, const int value, const int maximum) { - if (ok) *ok = true; - - const int val = dlg.getSpeedLimit(); - if (val < 0) - return 0; - return (val * 1024); - } - - return -2; -} + slider->setMaximum(maximum); + slider->setValue(value); + }; + const auto *session = BitTorrent::Session::instance(); + const int uploadVal = qMax(0, (session->globalUploadSpeedLimit() / 1024)); + const int downloadVal = qMax(0, (session->globalDownloadSpeedLimit() / 1024)); + const int maxUpload = qMax(10000, (session->globalUploadSpeedLimit() / 1024)); + const int maxDownload = qMax(10000, (session->globalDownloadSpeedLimit() / 1024)); + initSlider(m_ui->sliderUploadLimit, uploadVal, maxUpload); + initSlider(m_ui->sliderDownloadLimit, downloadVal, maxDownload); + + const int altUploadVal = qMax(0, (session->altGlobalUploadSpeedLimit() / 1024)); + const int altDownloadVal = qMax(0, (session->altGlobalDownloadSpeedLimit() / 1024)); + const int altMaxUpload = qMax(10000, (session->altGlobalUploadSpeedLimit() / 1024)); + const int altMaxDownload = qMax(10000, (session->altGlobalDownloadSpeedLimit() / 1024)); + initSlider(m_ui->sliderAltUploadLimit, altUploadVal, altMaxUpload); + initSlider(m_ui->sliderAltDownloadLimit, altDownloadVal, altMaxDownload); + + m_ui->spinUploadLimit->setValue(uploadVal); + m_ui->spinDownloadLimit->setValue(downloadVal); + m_ui->spinAltUploadLimit->setValue(altUploadVal); + m_ui->spinAltDownloadLimit->setValue(altDownloadVal); + + m_initialValues = + { + m_ui->spinUploadLimit->value(), + m_ui->spinDownloadLimit->value(), + m_ui->spinAltUploadLimit->value(), + m_ui->spinAltDownloadLimit->value() + }; + + // Sync up/down speed limit sliders with their corresponding spinboxes + connect(m_ui->sliderUploadLimit, &QSlider::valueChanged, m_ui->spinUploadLimit, &QSpinBox::setValue); + connect(m_ui->sliderDownloadLimit, &QSlider::valueChanged, m_ui->spinDownloadLimit, &QSpinBox::setValue); + connect(m_ui->spinUploadLimit, qOverload(&QSpinBox::valueChanged) + , this, [this](const int value) { updateSliderValue(m_ui->sliderUploadLimit, value); }); + connect(m_ui->spinDownloadLimit, qOverload(&QSpinBox::valueChanged) + , this, [this](const int value) { updateSliderValue(m_ui->sliderDownloadLimit, value); }); + connect(m_ui->sliderAltUploadLimit, &QSlider::valueChanged, m_ui->spinAltUploadLimit, &QSpinBox::setValue); + connect(m_ui->sliderAltDownloadLimit, &QSlider::valueChanged, m_ui->spinAltDownloadLimit, &QSpinBox::setValue); + connect(m_ui->spinAltUploadLimit, qOverload(&QSpinBox::valueChanged) + , this, [this](const int value) { updateSliderValue(m_ui->sliderAltUploadLimit, value); }); + connect(m_ui->spinAltDownloadLimit, qOverload(&QSpinBox::valueChanged) + , this, [this](const int value) { updateSliderValue(m_ui->sliderAltDownloadLimit, value); }); -void SpeedLimitDialog::updateSpinValue(const int value) -{ - m_ui->spinBandwidth->setValue(value); + Utils::Gui::resize(this); } -void SpeedLimitDialog::updateSliderValue(const int value) +SpeedLimitDialog::~SpeedLimitDialog() { - if (value > m_ui->bandwidthSlider->maximum()) - m_ui->bandwidthSlider->setMaximum(value); - m_ui->bandwidthSlider->setValue(value); + delete m_ui; } -int SpeedLimitDialog::getSpeedLimit() const +void SpeedLimitDialog::accept() { - return m_ui->spinBandwidth->value(); -} + auto *session = BitTorrent::Session::instance(); + const int uploadLimit = (m_ui->spinUploadLimit->value() * 1024); + if (m_initialValues.uploadSpeedLimit != m_ui->spinUploadLimit->value()) + session->setGlobalUploadSpeedLimit(uploadLimit); -void SpeedLimitDialog::setupDialog(long maxSlider, long val) -{ - val = qMax(0, val); + const int downloadLimit = (m_ui->spinDownloadLimit->value() * 1024); + if (m_initialValues.downloadSpeedLimit != m_ui->spinDownloadLimit->value()) + session->setGlobalDownloadSpeedLimit(downloadLimit); - if (maxSlider <= 0) - maxSlider = 10000; + const int altUploadLimit = (m_ui->spinAltUploadLimit->value() * 1024); + if (m_initialValues.altUploadSpeedLimit != m_ui->spinAltUploadLimit->value()) + session->setAltGlobalUploadSpeedLimit(altUploadLimit); - // This can happen for example if global rate limit is lower - // than torrent rate limit. - if (val > maxSlider) - maxSlider = val; + const int altDownloadLimit = (m_ui->spinAltDownloadLimit->value() * 1024); + if (m_initialValues.altDownloadSpeedLimit != m_ui->spinAltDownloadLimit->value()) + session->setAltGlobalDownloadSpeedLimit(altDownloadLimit); - m_ui->bandwidthSlider->setMaximum(maxSlider); - m_ui->bandwidthSlider->setValue(val); - updateSpinValue(val); + QDialog::accept(); } diff --git a/src/gui/speedlimitdialog.h b/src/gui/speedlimitdialog.h index b83702e02..1c3d77676 100644 --- a/src/gui/speedlimitdialog.h +++ b/src/gui/speedlimitdialog.h @@ -35,22 +35,24 @@ namespace Ui class SpeedLimitDialog; } -class SpeedLimitDialog : public QDialog +class SpeedLimitDialog final : public QDialog { Q_OBJECT public: explicit SpeedLimitDialog(QWidget *parent); - ~SpeedLimitDialog(); - static long askSpeedLimit(QWidget *parent, bool *ok, const QString &title, long defaultVal, long maxVal = 10240000); + ~SpeedLimitDialog() override; -private slots: - void updateSpinValue(int val); - void updateSliderValue(int val); +public slots: + void accept() override; private: - void setupDialog(long maxSlider, long val); - int getSpeedLimit() const; - Ui::SpeedLimitDialog *m_ui; + struct + { + int uploadSpeedLimit; + int downloadSpeedLimit; + int altUploadSpeedLimit; + int altDownloadSpeedLimit; + } m_initialValues; }; diff --git a/src/gui/speedlimitdialog.ui b/src/gui/speedlimitdialog.ui index 959676cc7..ea680b6a2 100644 --- a/src/gui/speedlimitdialog.ui +++ b/src/gui/speedlimitdialog.ui @@ -6,34 +6,166 @@ 0 0 - 338 - 83 + 481 + 272 + + Global Speed Limits + - - - - - Qt::Horizontal - - - - - - - - - - KiB/s - - - 65535 - - - - + + + Speed limits + + + + + + + + + + + + + Upload: + + + + + + + Qt::Horizontal + + + + + + + + + + KiB/s + + + 2000000 + + + + + + + Download: + + + + + + + Qt::Horizontal + + + + + + + + + + KiB/s + + + 2000000 + + + + + + + + + + Alternative speed limits + + + + + + + + + + + + + Upload: + + + + + + + Qt::Horizontal + + + + + + + + + + KiB/s + + + 2000000 + + + + + + + Download: + + + + + + + Qt::Horizontal + + + + + + + + + + KiB/s + + + 2000000 + + + + + + + + + + Qt::Vertical + + + + 20 + 0 + + + diff --git a/src/gui/statusbar.cpp b/src/gui/statusbar.cpp index 2554608b4..c990cca89 100644 --- a/src/gui/statusbar.cpp +++ b/src/gui/statusbar.cpp @@ -71,7 +71,7 @@ StatusBar::StatusBar(QWidget *parent) m_dlSpeedLbl = new QPushButton(this); m_dlSpeedLbl->setIcon(UIThemeManager::instance()->getIcon(QLatin1String("downloading_small"))); - connect(m_dlSpeedLbl, &QAbstractButton::clicked, this, &StatusBar::capDownloadSpeed); + connect(m_dlSpeedLbl, &QAbstractButton::clicked, this, &StatusBar::capSpeed); m_dlSpeedLbl->setFlat(true); m_dlSpeedLbl->setFocusPolicy(Qt::NoFocus); m_dlSpeedLbl->setCursor(Qt::PointingHandCursor); @@ -80,7 +80,7 @@ StatusBar::StatusBar(QWidget *parent) m_upSpeedLbl = new QPushButton(this); m_upSpeedLbl->setIcon(UIThemeManager::instance()->getIcon(QLatin1String("seeding"))); - connect(m_upSpeedLbl, &QAbstractButton::clicked, this, &StatusBar::capUploadSpeed); + connect(m_upSpeedLbl, &QAbstractButton::clicked, this, &StatusBar::capSpeed); m_upSpeedLbl->setFlat(true); m_upSpeedLbl->setFocusPolicy(Qt::NoFocus); m_upSpeedLbl->setCursor(Qt::PointingHandCursor); @@ -251,32 +251,9 @@ void StatusBar::updateAltSpeedsBtn(bool alternative) refresh(); } -void StatusBar::capDownloadSpeed() +void StatusBar::capSpeed() { - BitTorrent::Session *const session = BitTorrent::Session::instance(); - - bool ok = false; - const long newLimit = SpeedLimitDialog::askSpeedLimit( - parentWidget(), &ok, tr("Global Download Speed Limit"), session->downloadSpeedLimit()); - if (ok) - { - qDebug("Setting global download rate limit to %.1fKb/s", newLimit / 1024.); - session->setDownloadSpeedLimit(newLimit); - refresh(); - } -} - -void StatusBar::capUploadSpeed() -{ - BitTorrent::Session *const session = BitTorrent::Session::instance(); - - bool ok = false; - const long newLimit = SpeedLimitDialog::askSpeedLimit( - parentWidget(), &ok, tr("Global Upload Speed Limit"), session->uploadSpeedLimit()); - if (ok) - { - qDebug("Setting global upload rate limit to %.1fKb/s", newLimit / 1024.); - session->setUploadSpeedLimit(newLimit); - refresh(); - } + auto dialog = new SpeedLimitDialog {parentWidget()}; + dialog->setAttribute(Qt::WA_DeleteOnClose); + dialog->open(); } diff --git a/src/gui/statusbar.h b/src/gui/statusbar.h index 2bcebd1c7..8961385f7 100644 --- a/src/gui/statusbar.h +++ b/src/gui/statusbar.h @@ -57,8 +57,7 @@ public slots: private slots: void refresh(); void updateAltSpeedsBtn(bool alternative); - void capDownloadSpeed(); - void capUploadSpeed(); + void capSpeed(); private: void updateConnectionStatus(); diff --git a/src/gui/torrentoptionsdialog.cpp b/src/gui/torrentoptionsdialog.cpp new file mode 100644 index 000000000..b80122573 --- /dev/null +++ b/src/gui/torrentoptionsdialog.cpp @@ -0,0 +1,368 @@ +/* + * Bittorrent Client using Qt and libtorrent. + * Copyright (C) 2006 Christophe Dumez + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + */ + +#include "torrentoptionsdialog.h" + +#include +#include + +#include "base/bittorrent/infohash.h" +#include "base/bittorrent/session.h" +#include "base/bittorrent/torrenthandle.h" +#include "base/global.h" +#include "base/unicodestrings.h" +#include "ui_torrentoptionsdialog.h" +#include "utils.h" + +namespace +{ + const int MIXED_SHARE_LIMITS = -9; + + void updateSliderValue(QSlider *slider, const int value) + { + if (value > slider->maximum()) + slider->setMaximum(value); + slider->setValue(value); + } +} + +TorrentOptionsDialog::TorrentOptionsDialog(QWidget *parent, const QVector &torrents) + : QDialog {parent} + , m_ui {new Ui::TorrentOptionsDialog} +{ + m_ui->setupUi(this); + + Q_ASSERT(!torrents.empty()); + const auto *session = BitTorrent::Session::instance(); + bool allSameUpLimit = true, allSameDownLimit = true, allSameRatio = true, allSameSeedingTime = true + , allTorrentsArePrivate = true, allSameDHT = true, allSamePEX = true, allSameLSD = true; + + const int firstTorrentUpLimit = qMax(0, torrents[0]->uploadLimit()); + const int firstTorrentDownLimit = qMax(0, torrents[0]->downloadLimit()); + + const qreal firstTorrentRatio = torrents[0]->ratioLimit(); + const int firstTorrentSeedingTime = torrents[0]->seedingTimeLimit(); + + const bool isFirstTorrentDHTDisabled = torrents[0]->isDHTDisabled(); + const bool isFirstTorrentPEXDisabled = torrents[0]->isPEXDisabled(); + const bool isFirstTorrentLSDDisabled = torrents[0]->isLSDDisabled(); + + m_torrentHashes.reserve(torrents.size()); + for (const BitTorrent::TorrentHandle *torrent : torrents) + { + m_torrentHashes << torrent->hash(); + if (allSameUpLimit) + { + if (qMax(0, torrent->uploadLimit()) != firstTorrentUpLimit) + allSameUpLimit = false; + } + if (allSameDownLimit) + { + if (qMax(0, torrent->downloadLimit()) != firstTorrentDownLimit) + allSameDownLimit = false; + } + if (allSameRatio) + { + if (torrent->ratioLimit() != firstTorrentRatio) + allSameRatio = false; + } + if (allSameSeedingTime) + { + if (torrent->seedingTimeLimit() != firstTorrentSeedingTime) + allSameSeedingTime = false; + } + if (allTorrentsArePrivate) + { + if (!torrent->isPrivate()) + allTorrentsArePrivate = false; + } + if (allSameDHT) + { + if (torrent->isDHTDisabled() != isFirstTorrentDHTDisabled) + { + m_ui->checkDisableDHT->setCheckState(Qt::PartiallyChecked); + allSameDHT = false; + } + } + if (allSamePEX) + { + if (torrent->isPEXDisabled() != isFirstTorrentPEXDisabled) + { + m_ui->checkDisablePEX->setCheckState(Qt::PartiallyChecked); + allSamePEX = false; + } + } + if (allSameLSD) + { + if (torrent->isLSDDisabled() != isFirstTorrentLSDDisabled) + { + m_ui->checkDisableLSD->setCheckState(Qt::PartiallyChecked); + allSameLSD = false; + } + } + } + + const bool isAltLimitEnabled = session->isAltGlobalSpeedLimitEnabled(); + const int globalUploadLimit = isAltLimitEnabled + ? (session->altGlobalUploadSpeedLimit() / 1024) + : (session->globalUploadSpeedLimit() / 1024); + const int globalDownloadLimit = isAltLimitEnabled + ? (session->altGlobalDownloadSpeedLimit() / 1024) + : (session->globalDownloadSpeedLimit() / 1024); + + const int uploadVal = qMax(0, (firstTorrentUpLimit / 1024)); + const int downloadVal = qMax(0, (firstTorrentDownLimit / 1024)); + int maxUpload = (globalUploadLimit <= 0) ? 10000 : globalUploadLimit; + int maxDownload = (globalDownloadLimit <= 0) ? 10000 : globalDownloadLimit; + + // This can happen for example if global rate limit is lower than torrent rate limit. + if (uploadVal > maxUpload) + maxUpload = uploadVal; + if (downloadVal > maxDownload) + maxDownload = downloadVal; + + m_ui->sliderUploadLimit->setMaximum(maxUpload); + m_ui->sliderUploadLimit->setValue(allSameUpLimit ? uploadVal : (maxUpload / 2)); + if (allSameUpLimit) + { + m_ui->spinUploadLimit->setValue(uploadVal); + } + else + { + m_ui->spinUploadLimit->setSpecialValueText(QString::fromUtf8(C_INEQUALITY)); + m_ui->spinUploadLimit->setMinimum(-1); + m_ui->spinUploadLimit->setValue(-1); + connect(m_ui->spinUploadLimit, qOverload(&QSpinBox::valueChanged) + , this, &TorrentOptionsDialog::handleUpSpeedLimitChanged); + } + + m_ui->sliderDownloadLimit->setMaximum(maxDownload); + m_ui->sliderDownloadLimit->setValue(allSameDownLimit ? downloadVal : (maxDownload / 2)); + if (allSameDownLimit) + { + m_ui->spinDownloadLimit->setValue(downloadVal); + } + else + { + m_ui->spinDownloadLimit->setSpecialValueText(QString::fromUtf8(C_INEQUALITY)); + m_ui->spinDownloadLimit->setMinimum(-1); + m_ui->spinDownloadLimit->setValue(-1); + connect(m_ui->spinDownloadLimit, qOverload(&QSpinBox::valueChanged) + , this, &TorrentOptionsDialog::handleDownSpeedLimitChanged); + } + + const bool useGlobalValue = allSameRatio && allSameSeedingTime + && (firstTorrentRatio == BitTorrent::TorrentHandle::USE_GLOBAL_RATIO) + && (firstTorrentSeedingTime == BitTorrent::TorrentHandle::USE_GLOBAL_SEEDING_TIME); + + if (!allSameRatio || !allSameSeedingTime) + { + m_ui->radioUseGlobalShareLimits->setChecked(false); + m_ui->radioNoLimit->setChecked(false); + m_ui->radioTorrentLimit->setChecked(false); + } + else if (useGlobalValue) + { + m_ui->radioUseGlobalShareLimits->setChecked(true); + } + else if ((firstTorrentRatio == BitTorrent::TorrentHandle::NO_RATIO_LIMIT) + && (firstTorrentSeedingTime == BitTorrent::TorrentHandle::NO_SEEDING_TIME_LIMIT)) + { + m_ui->radioNoLimit->setChecked(true); + } + else + { + m_ui->radioTorrentLimit->setChecked(true); + if (firstTorrentRatio >= 0) + m_ui->checkMaxRatio->setChecked(true); + if (firstTorrentSeedingTime >= 0) + m_ui->checkMaxTime->setChecked(true); + } + + const qreal maxRatio = (allSameRatio && (firstTorrentRatio >= 0)) + ? firstTorrentRatio : session->globalMaxRatio(); + const int maxSeedingTime = (allSameSeedingTime && (firstTorrentSeedingTime >= 0)) + ? firstTorrentSeedingTime : session->globalMaxSeedingMinutes(); + m_ui->spinRatioLimit->setValue(maxRatio); + m_ui->spinTimeLimit->setValue(maxSeedingTime); + handleRatioTypeChanged(); + + if (!allTorrentsArePrivate) + { + if (m_ui->checkDisableDHT->checkState() != Qt::PartiallyChecked) + m_ui->checkDisableDHT->setChecked(isFirstTorrentDHTDisabled); + if (m_ui->checkDisablePEX->checkState() != Qt::PartiallyChecked) + m_ui->checkDisablePEX->setChecked(isFirstTorrentPEXDisabled); + if (m_ui->checkDisableLSD->checkState() != Qt::PartiallyChecked) + m_ui->checkDisableLSD->setChecked(isFirstTorrentLSDDisabled); + } + else + { + m_ui->checkDisableDHT->setChecked(true); + m_ui->checkDisableDHT->setEnabled(false); + m_ui->checkDisablePEX->setChecked(true); + m_ui->checkDisablePEX->setEnabled(false); + m_ui->checkDisableLSD->setChecked(true); + m_ui->checkDisableLSD->setEnabled(false); + } + + const QString privateTorrentsTooltip = tr("Not applicable to private torrents"); + m_ui->checkDisableDHT->setToolTip(privateTorrentsTooltip); + m_ui->checkDisablePEX->setToolTip(privateTorrentsTooltip); + m_ui->checkDisableLSD->setToolTip(privateTorrentsTooltip); + + m_initialValues = + { + getRatio(), + getSeedingTime(), + m_ui->spinUploadLimit->value(), + m_ui->spinDownloadLimit->value(), + m_ui->checkDisableDHT->checkState(), + m_ui->checkDisablePEX->checkState(), + m_ui->checkDisableLSD->checkState() + }; + + // Sync up/down speed limit sliders with their corresponding spinboxes + connect(m_ui->sliderUploadLimit, &QSlider::valueChanged, m_ui->spinUploadLimit, &QSpinBox::setValue); + connect(m_ui->sliderDownloadLimit, &QSlider::valueChanged, m_ui->spinDownloadLimit, &QSpinBox::setValue); + connect(m_ui->spinUploadLimit, qOverload(&QSpinBox::valueChanged) + , this, [this](const int value) { updateSliderValue(m_ui->sliderUploadLimit, value); }); + connect(m_ui->spinDownloadLimit, qOverload(&QSpinBox::valueChanged) + , this, [this](const int value) { updateSliderValue(m_ui->sliderDownloadLimit, value); }); + + connect(m_ui->checkMaxRatio, &QCheckBox::toggled, m_ui->spinRatioLimit, &QDoubleSpinBox::setEnabled); + connect(m_ui->checkMaxTime, &QCheckBox::toggled, m_ui->spinTimeLimit, &QSpinBox::setEnabled); + +#if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)) + connect(m_ui->buttonGroup, &QButtonGroup::idClicked, this, &TorrentOptionsDialog::handleRatioTypeChanged); +#else + connect(m_ui->buttonGroup, qOverload(&QButtonGroup::buttonClicked) + , this, &TorrentOptionsDialog::handleRatioTypeChanged); +#endif + + Utils::Gui::resize(this); +} + +TorrentOptionsDialog::~TorrentOptionsDialog() +{ + delete m_ui; +} + +void TorrentOptionsDialog::accept() +{ + if (m_ui->radioTorrentLimit->isChecked() && !m_ui->checkMaxRatio->isChecked() && !m_ui->checkMaxTime->isChecked()) + { + QMessageBox::critical(this, tr("No share limit method selected"), tr("Please select a limit method first")); + return; + } + + const auto *session = BitTorrent::Session::instance(); + for (const BitTorrent::InfoHash &hash : asConst(m_torrentHashes)) + { + BitTorrent::TorrentHandle *torrent = session->findTorrent(hash); + if (!torrent) continue; + + if (m_initialValues.upSpeedLimit != m_ui->spinUploadLimit->value()) + torrent->setUploadLimit(m_ui->spinUploadLimit->value() * 1024); + if (m_initialValues.downSpeedLimit != m_ui->spinDownloadLimit->value()) + torrent->setDownloadLimit(m_ui->spinDownloadLimit->value() * 1024); + + const qreal ratioLimit = getRatio(); + if (m_initialValues.ratio != ratioLimit) + torrent->setRatioLimit(ratioLimit); + + const int seedingTimeLimit = getSeedingTime(); + if (m_initialValues.seedingTime != seedingTimeLimit) + torrent->setSeedingTimeLimit(seedingTimeLimit); + + if (!torrent->isPrivate()) + { + if (m_initialValues.disableDHT != m_ui->checkDisableDHT->checkState()) + torrent->setDHTDisabled(m_ui->checkDisableDHT->isChecked()); + if (m_initialValues.disablePEX != m_ui->checkDisablePEX->checkState()) + torrent->setPEXDisabled(m_ui->checkDisablePEX->isChecked()); + if (m_initialValues.disableLSD != m_ui->checkDisableLSD->checkState()) + torrent->setLSDDisabled(m_ui->checkDisableLSD->isChecked()); + } + } + + QDialog::accept(); +} + +qreal TorrentOptionsDialog::getRatio() const +{ + if (m_ui->buttonGroup->checkedId() == -1) // No radio button is selected + return MIXED_SHARE_LIMITS; + + if (m_ui->radioUseGlobalShareLimits->isChecked()) + return BitTorrent::TorrentHandle::USE_GLOBAL_RATIO; + + if (m_ui->radioNoLimit->isChecked() || !m_ui->checkMaxRatio->isChecked()) + return BitTorrent::TorrentHandle::NO_RATIO_LIMIT; + + return m_ui->spinRatioLimit->value(); +} + +int TorrentOptionsDialog::getSeedingTime() const +{ + if (m_ui->buttonGroup->checkedId() == -1) // No radio button is selected + return MIXED_SHARE_LIMITS; + + if (m_ui->radioUseGlobalShareLimits->isChecked()) + return BitTorrent::TorrentHandle::USE_GLOBAL_SEEDING_TIME; + + if (m_ui->radioNoLimit->isChecked() || !m_ui->checkMaxTime->isChecked()) + return BitTorrent::TorrentHandle::NO_SEEDING_TIME_LIMIT; + + return m_ui->spinTimeLimit->value(); +} + +void TorrentOptionsDialog::handleRatioTypeChanged() +{ + m_ui->checkMaxRatio->setEnabled(m_ui->radioTorrentLimit->isChecked()); + m_ui->checkMaxTime->setEnabled(m_ui->radioTorrentLimit->isChecked()); + + m_ui->spinRatioLimit->setEnabled(m_ui->radioTorrentLimit->isChecked() && m_ui->checkMaxRatio->isChecked()); + m_ui->spinTimeLimit->setEnabled(m_ui->radioTorrentLimit->isChecked() && m_ui->checkMaxTime->isChecked()); +} + +void TorrentOptionsDialog::handleUpSpeedLimitChanged() +{ + m_ui->spinUploadLimit->setMinimum(0); + m_ui->spinUploadLimit->setSpecialValueText(QString::fromUtf8(C_INFINITY)); + disconnect(m_ui->spinUploadLimit, qOverload(&QSpinBox::valueChanged) + , this, &TorrentOptionsDialog::handleUpSpeedLimitChanged); +} + +void TorrentOptionsDialog::handleDownSpeedLimitChanged() +{ + m_ui->spinDownloadLimit->setMinimum(0); + m_ui->spinDownloadLimit->setSpecialValueText(QString::fromUtf8(C_INFINITY)); + disconnect(m_ui->spinDownloadLimit, qOverload(&QSpinBox::valueChanged) + , this, &TorrentOptionsDialog::handleDownSpeedLimitChanged); +} diff --git a/src/gui/updownratiodialog.h b/src/gui/torrentoptionsdialog.h similarity index 65% rename from src/gui/updownratiodialog.h rename to src/gui/torrentoptionsdialog.h index af55c0d45..ac64a9e5f 100644 --- a/src/gui/updownratiodialog.h +++ b/src/gui/torrentoptionsdialog.h @@ -1,7 +1,7 @@ /* * Bittorrent Client using Qt and libtorrent. - * Copyright (C) 2011 Christian Kandeler - * Copyright (C) 2011 Christophe Dumez + * Copyright (C) 2006 Christophe Dumez + * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 @@ -30,33 +30,48 @@ #include +namespace BitTorrent +{ + class InfoHash; + class TorrentHandle; +} + namespace Ui { - class UpDownRatioDialog; + class TorrentOptionsDialog; } -class UpDownRatioDialog final : public QDialog +class TorrentOptionsDialog final : public QDialog { Q_OBJECT public: - UpDownRatioDialog(bool useDefault, qreal initialValue, qreal maxValue, - int initialTimeValue, int maxTimeValue, - QWidget *parent = nullptr); - ~UpDownRatioDialog(); - - bool useDefault() const; - qreal ratio() const; - int seedingTime() const; + explicit TorrentOptionsDialog(QWidget *parent, const QVector &torrents); + ~TorrentOptionsDialog() override; public slots: void accept() override; private slots: + void handleUpSpeedLimitChanged(); + void handleDownSpeedLimitChanged(); + void handleRatioTypeChanged(); - void enableRatioSpin(); - void enableTimeSpin(); private: - Ui::UpDownRatioDialog *m_ui; + qreal getRatio() const; + int getSeedingTime() const; + + QVector m_torrentHashes; + Ui::TorrentOptionsDialog *m_ui; + struct + { + qreal ratio; + int seedingTime; + int upSpeedLimit; + int downSpeedLimit; + Qt::CheckState disableDHT; + Qt::CheckState disablePEX; + Qt::CheckState disableLSD; + } m_initialValues; }; diff --git a/src/gui/torrentoptionsdialog.ui b/src/gui/torrentoptionsdialog.ui new file mode 100644 index 000000000..b033d5c92 --- /dev/null +++ b/src/gui/torrentoptionsdialog.ui @@ -0,0 +1,278 @@ + + + TorrentOptionsDialog + + + + 0 + 0 + 390 + 450 + + + + Torrent Options + + + + + + Torrent speed limits + + + + + + Download: + + + + + + + + + + KiB/s + + + 2000000 + + + + + + + + + + KiB/s + + + 2000000 + + + + + + + These will not exceed the global limits + + + + + + + Upload: + + + + + + + Qt::Horizontal + + + + + + + Qt::Horizontal + + + + + + + + + + Torrent share limits + + + + + + Use global share limit + + + buttonGroup + + + + + + + Set no share limit + + + buttonGroup + + + + + + + + + Set share limit to + + + buttonGroup + + + + + + + minutes + + + + + + + 9999.000000000000000 + + + 0.050000000000000 + + + 1.000000000000000 + + + + + + + 525600 + + + 1440 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + ratio + + + + + + + + + + + + + + Disable DHT for this torrent + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Disable PeX for this torrent + + + + + + + Disable LSD for this torrent + + + + + + + + + Qt::Vertical + + + + 20 + 0 + + + + + + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + buttonBox + rejected() + TorrentOptionsDialog + reject() + + + 221 + 73 + + + 221 + 82 + + + + + buttonBox + accepted() + TorrentOptionsDialog + accept() + + + 277 + 59 + + + 343 + 80 + + + + + + + + diff --git a/src/gui/transferlistwidget.cpp b/src/gui/transferlistwidget.cpp index 4e17233cb..798756c0a 100644 --- a/src/gui/transferlistwidget.cpp +++ b/src/gui/transferlistwidget.cpp @@ -62,13 +62,13 @@ #include "previewselectdialog.h" #include "speedlimitdialog.h" #include "torrentcategorydialog.h" +#include "torrentoptionsdialog.h" #include "trackerentriesdialog.h" #include "transferlistdelegate.h" #include "transferlistmodel.h" #include "transferlistsortmodel.h" #include "tristateaction.h" #include "uithememanager.h" -#include "updownratiodialog.h" #include "utils.h" #ifdef Q_OS_MACOS @@ -551,102 +551,13 @@ void TransferListWidget::previewSelectedTorrents() } } -void TransferListWidget::setDlLimitSelectedTorrents() +void TransferListWidget::setTorrentOptions() { - QVector torrentsList; - for (BitTorrent::TorrentHandle *const torrent : asConst(getSelectedTorrents())) - { - if (torrent->isSeed()) - continue; - torrentsList += torrent; - } - if (torrentsList.empty()) return; - - int oldLimit = torrentsList.first()->downloadLimit(); - for (BitTorrent::TorrentHandle *const torrent : asConst(torrentsList)) - { - if (torrent->downloadLimit() != oldLimit) - { - oldLimit = -1; - break; - } - } - - bool ok = false; - const long newLimit = SpeedLimitDialog::askSpeedLimit( - this, &ok, tr("Torrent Download Speed Limiting"), oldLimit - , BitTorrent::Session::instance()->globalDownloadSpeedLimit()); - if (!ok) return; - - for (BitTorrent::TorrentHandle *const torrent : asConst(torrentsList)) - { - qDebug("Applying download speed limit of %ld Kb/s to torrent %s", (newLimit / 1024l), qUtf8Printable(torrent->hash())); - torrent->setDownloadLimit(newLimit); - } -} + const QVector selectedTorrents = getSelectedTorrents(); + if (selectedTorrents.empty()) return; -void TransferListWidget::setUpLimitSelectedTorrents() -{ - QVector torrentsList = getSelectedTorrents(); - if (torrentsList.empty()) return; - - int oldLimit = torrentsList.first()->uploadLimit(); - for (BitTorrent::TorrentHandle *const torrent : asConst(torrentsList)) - { - if (torrent->uploadLimit() != oldLimit) - { - oldLimit = -1; - break; - } - } - - bool ok = false; - const long newLimit = SpeedLimitDialog::askSpeedLimit( - this, &ok, tr("Torrent Upload Speed Limiting"), oldLimit - , BitTorrent::Session::instance()->globalUploadSpeedLimit()); - if (!ok) return; - - for (BitTorrent::TorrentHandle *const torrent : asConst(torrentsList)) - { - qDebug("Applying upload speed limit of %ld Kb/s to torrent %s", (newLimit / 1024l), qUtf8Printable(torrent->hash())); - torrent->setUploadLimit(newLimit); - } -} - -void TransferListWidget::setMaxRatioSelectedTorrents() -{ - const QVector torrents = getSelectedTorrents(); - if (torrents.isEmpty()) return; - - qreal currentMaxRatio = BitTorrent::Session::instance()->globalMaxRatio(); - if (torrents.count() == 1) - currentMaxRatio = torrents[0]->maxRatio(); - - int currentMaxSeedingTime = BitTorrent::Session::instance()->globalMaxSeedingMinutes(); - if (torrents.count() == 1) - currentMaxSeedingTime = torrents[0]->maxSeedingTime(); - - bool useGlobalValue = true; - if (torrents.count() == 1) - useGlobalValue = (torrents[0]->ratioLimit() == BitTorrent::TorrentHandle::USE_GLOBAL_RATIO) - && (torrents[0]->seedingTimeLimit() == BitTorrent::TorrentHandle::USE_GLOBAL_SEEDING_TIME); - - auto dialog = new UpDownRatioDialog(useGlobalValue, currentMaxRatio, BitTorrent::TorrentHandle::MAX_RATIO, - currentMaxSeedingTime, BitTorrent::TorrentHandle::MAX_SEEDING_TIME, this); + auto dialog = new TorrentOptionsDialog {this, selectedTorrents}; dialog->setAttribute(Qt::WA_DeleteOnClose); - connect(dialog, &QDialog::accepted, this, [dialog, torrents]() - { - for (BitTorrent::TorrentHandle *const torrent : torrents) - { - const qreal ratio = (dialog->useDefault() - ? BitTorrent::TorrentHandle::USE_GLOBAL_RATIO : dialog->ratio()); - torrent->setRatioLimit(ratio); - - const int seedingTime = (dialog->useDefault() - ? BitTorrent::TorrentHandle::USE_GLOBAL_SEEDING_TIME : dialog->seedingTime()); - torrent->setSeedingTimeLimit(seedingTime); - } - }); dialog->open(); } @@ -897,12 +808,8 @@ void TransferListWidget::displayListMenu(const QPoint &) connect(actionDelete, &QAction::triggered, this, &TransferListWidget::softDeleteSelectedTorrents); auto *actionPreviewFile = new QAction(UIThemeManager::instance()->getIcon("view-preview"), tr("Preview file..."), listMenu); connect(actionPreviewFile, &QAction::triggered, this, &TransferListWidget::previewSelectedTorrents); - auto *actionSetMaxRatio = new QAction(UIThemeManager::instance()->getIcon(QLatin1String("ratio")), tr("Limit share ratio..."), listMenu); - connect(actionSetMaxRatio, &QAction::triggered, this, &TransferListWidget::setMaxRatioSelectedTorrents); - auto *actionSetUploadLimit = new QAction(UIThemeManager::instance()->getIcon("kt-set-max-upload-speed"), tr("Limit upload rate..."), listMenu); - connect(actionSetUploadLimit, &QAction::triggered, this, &TransferListWidget::setUpLimitSelectedTorrents); - auto *actionSetDownloadLimit = new QAction(UIThemeManager::instance()->getIcon("kt-set-max-download-speed"), tr("Limit download rate..."), listMenu); - connect(actionSetDownloadLimit, &QAction::triggered, this, &TransferListWidget::setDlLimitSelectedTorrents); + auto *actionTorrentOptions = new QAction(UIThemeManager::instance()->getIcon("configure"), tr("Torrent options..."), listMenu); + connect(actionTorrentOptions, &QAction::triggered, this, &TransferListWidget::setTorrentOptions); auto *actionOpenDestinationFolder = new QAction(UIThemeManager::instance()->getIcon("inode-directory"), tr("Open destination folder"), listMenu); connect(actionOpenDestinationFolder, &QAction::triggered, this, &TransferListWidget::openSelectedTorrentsFolder); auto *actionIncreaseQueuePos = new QAction(UIThemeManager::instance()->getIcon("go-up"), tr("Move up", "i.e. move up in the queue"), listMenu); @@ -1132,10 +1039,7 @@ void TransferListWidget::displayListMenu(const QPoint &) listMenu->addAction(actionAutoTMM); listMenu->addSeparator(); - if (oneNotSeed) - listMenu->addAction(actionSetDownloadLimit); - listMenu->addAction(actionSetUploadLimit); - listMenu->addAction(actionSetMaxRatio); + listMenu->addAction(actionTorrentOptions); if (!oneNotSeed && oneHasMetadata) { actionSuperSeedingMode->setCheckState(allSameSuperSeeding diff --git a/src/gui/transferlistwidget.h b/src/gui/transferlistwidget.h index b809f50eb..1380a7514 100644 --- a/src/gui/transferlistwidget.h +++ b/src/gui/transferlistwidget.h @@ -79,9 +79,7 @@ public slots: void openSelectedTorrentsFolder() const; void recheckSelectedTorrents(); void reannounceSelectedTorrents(); - void setDlLimitSelectedTorrents(); - void setUpLimitSelectedTorrents(); - void setMaxRatioSelectedTorrents(); + void setTorrentOptions(); void previewSelectedTorrents(); void hideQueuePosColumn(bool hide); void displayDLHoSMenu(const QPoint&); diff --git a/src/gui/updownratiodialog.cpp b/src/gui/updownratiodialog.cpp deleted file mode 100644 index fe75dbdb0..000000000 --- a/src/gui/updownratiodialog.cpp +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Bittorrent Client using Qt and libtorrent. - * Copyright (C) 2011 Christian Kandeler - * Copyright (C) 2011 Christophe Dumez - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * In addition, as a special exception, the copyright holders give permission to - * link this program with the OpenSSL project's "OpenSSL" library (or with - * modified versions of it that use the same license as the "OpenSSL" library), - * and distribute the linked executables. You must obey the GNU General Public - * License in all respects for all of the code used other than "OpenSSL". If you - * modify file(s), you may extend this exception to your version of the file(s), - * but you are not obligated to do so. If you do not wish to do so, delete this - * exception statement from your version. - */ - -#include "updownratiodialog.h" - -#include - -#include "base/bittorrent/session.h" -#include "ui_updownratiodialog.h" -#include "utils.h" - -UpDownRatioDialog::UpDownRatioDialog(bool useDefault, qreal initialRatioValue, - qreal maxRatioValue, int initialTimeValue, - int maxTimeValue, QWidget *parent) - : QDialog(parent) - , m_ui(new Ui::UpDownRatioDialog) -{ - m_ui->setupUi(this); - - if (useDefault) - { - m_ui->useDefaultButton->setChecked(true); - } - else if ((initialRatioValue == -1.) && (initialTimeValue == -1)) - { - m_ui->noLimitButton->setChecked(true); - initialRatioValue = BitTorrent::Session::instance()->globalMaxRatio(); - initialTimeValue = BitTorrent::Session::instance()->globalMaxSeedingMinutes(); - } - else - { - m_ui->torrentLimitButton->setChecked(true); - - if (initialRatioValue >= 0) - m_ui->checkMaxRatio->setChecked(true); - - if (initialTimeValue >= 0) - m_ui->checkMaxTime->setChecked(true); - } - - m_ui->ratioSpinBox->setMinimum(0); - m_ui->ratioSpinBox->setMaximum(maxRatioValue); - m_ui->ratioSpinBox->setValue(initialRatioValue); - - m_ui->timeSpinBox->setMinimum(0); - m_ui->timeSpinBox->setMaximum(maxTimeValue); - m_ui->timeSpinBox->setValue(initialTimeValue); - -#if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)) - connect(m_ui->buttonGroup, &QButtonGroup::idClicked - , this, &UpDownRatioDialog::handleRatioTypeChanged); -#else - connect(m_ui->buttonGroup, qOverload(&QButtonGroup::buttonClicked) - , this, &UpDownRatioDialog::handleRatioTypeChanged); -#endif - connect(m_ui->checkMaxRatio, &QCheckBox::toggled, this, &UpDownRatioDialog::enableRatioSpin); - connect(m_ui->checkMaxTime, &QCheckBox::toggled, this, &UpDownRatioDialog::enableTimeSpin); - - handleRatioTypeChanged(); - - Utils::Gui::resize(this); -} - -void UpDownRatioDialog::accept() -{ - if (m_ui->torrentLimitButton->isChecked() && !m_ui->checkMaxRatio->isChecked() && !m_ui->checkMaxTime->isChecked()) - QMessageBox::critical(this, tr("No share limit method selected"), - tr("Please select a limit method first")); - else - QDialog::accept(); -} - -bool UpDownRatioDialog::useDefault() const -{ - return m_ui->useDefaultButton->isChecked(); -} - -qreal UpDownRatioDialog::ratio() const -{ - return (m_ui->noLimitButton->isChecked() || !m_ui->checkMaxRatio->isChecked()) ? -1. : m_ui->ratioSpinBox->value(); -} - -int UpDownRatioDialog::seedingTime() const -{ - return (m_ui->noLimitButton->isChecked() || !m_ui->checkMaxTime->isChecked()) ? -1 : m_ui->timeSpinBox->value(); -} - -void UpDownRatioDialog::handleRatioTypeChanged() -{ - // ui->ratioSpinBox->setEnabled(ui->torrentLimitButton->isChecked()); - m_ui->checkMaxRatio->setEnabled(m_ui->torrentLimitButton->isChecked()); - m_ui->checkMaxTime->setEnabled(m_ui->torrentLimitButton->isChecked()); - - m_ui->ratioSpinBox->setEnabled(m_ui->torrentLimitButton->isChecked() && m_ui->checkMaxRatio->isChecked()); - m_ui->timeSpinBox->setEnabled(m_ui->torrentLimitButton->isChecked() && m_ui->checkMaxTime->isChecked()); -} - -void UpDownRatioDialog::enableRatioSpin() -{ - m_ui->ratioSpinBox->setEnabled(m_ui->checkMaxRatio->isChecked()); -} - -void UpDownRatioDialog::enableTimeSpin() -{ - m_ui->timeSpinBox->setEnabled(m_ui->checkMaxTime->isChecked()); -} - -UpDownRatioDialog::~UpDownRatioDialog() -{ - delete m_ui; -} diff --git a/src/gui/updownratiodialog.ui b/src/gui/updownratiodialog.ui deleted file mode 100644 index edfef4312..000000000 --- a/src/gui/updownratiodialog.ui +++ /dev/null @@ -1,177 +0,0 @@ - - - UpDownRatioDialog - - - - 0 - 0 - 399 - 195 - - - - Torrent Upload/Download Ratio Limiting - - - - - - Use global share limit - - - buttonGroup - - - - - - - Set no share limit - - - buttonGroup - - - - - - - - - Set share limit to - - - buttonGroup - - - - - - - 9998.000000000000000 - - - 0.050000000000000 - - - 1.000000000000000 - - - - - - - - 0 - 0 - - - - 0 - - - 525600.000000000000000 - - - 1.000000000000000 - - - 1440.000000000000000 - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - ratio - - - - - - - minutes - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - Qt::Horizontal - - - QDialogButtonBox::Cancel|QDialogButtonBox::Ok - - - - - - - - - buttonBox - accepted() - UpDownRatioDialog - accept() - - - 248 - 254 - - - 157 - 274 - - - - - buttonBox - rejected() - UpDownRatioDialog - reject() - - - 316 - 260 - - - 286 - 274 - - - - - - - - -