Browse Source

Merge pull request #14137 from glassez/std-optional

Use std::optional for optional parameters
adaptive-webui-19844
Vladimir Golovnev 4 years ago committed by GitHub
parent
commit
7b657c942d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 10
      src/app/application.cpp
  2. 40
      src/app/cmdoptions.cpp
  3. 7
      src/app/cmdoptions.h
  4. 2
      src/base/CMakeLists.txt
  5. 2
      src/base/base.pri
  6. 11
      src/base/bittorrent/addtorrentparams.h
  7. 15
      src/base/bittorrent/session.cpp
  8. 3
      src/base/rss/rss_autodownloader.cpp
  9. 82
      src/base/rss/rss_autodownloadrule.cpp
  10. 12
      src/base/rss/rss_autodownloadrule.h
  11. 4
      src/base/scanfoldersmodel.cpp
  12. 44
      src/base/tristatebool.cpp
  13. 73
      src/base/tristatebool.h
  14. 11
      src/base/utils/string.cpp
  15. 4
      src/base/utils/string.h
  16. 15
      src/gui/addnewtorrentdialog.cpp
  17. 14
      src/gui/rss/automatedrssdownloader.cpp
  18. 2
      src/gui/torrentcreatordialog.cpp
  19. 8
      src/webui/api/logcontroller.cpp
  20. 2
      src/webui/api/rsscontroller.cpp
  21. 2
      src/webui/api/searchcontroller.cpp
  22. 26
      src/webui/api/torrentscontroller.cpp

10
src/app/application.cpp

@ -505,7 +505,7 @@ void Application::processParams(const QStringList &params)
} }
#endif #endif
BitTorrent::AddTorrentParams torrentParams; BitTorrent::AddTorrentParams torrentParams;
TriStateBool skipTorrentDialog; std::optional<bool> skipTorrentDialog;
for (QString param : params) for (QString param : params)
{ {
@ -521,7 +521,7 @@ void Application::processParams(const QStringList &params)
if (param.startsWith(QLatin1String("@addPaused="))) if (param.startsWith(QLatin1String("@addPaused=")))
{ {
torrentParams.addPaused = param.midRef(11).toInt() ? TriStateBool::True : TriStateBool::False; torrentParams.addPaused = (param.midRef(11).toInt() != 0);
continue; continue;
} }
@ -551,7 +551,7 @@ void Application::processParams(const QStringList &params)
if (param.startsWith(QLatin1String("@skipDialog="))) if (param.startsWith(QLatin1String("@skipDialog=")))
{ {
skipTorrentDialog = param.midRef(12).toInt() ? TriStateBool::True : TriStateBool::False; skipTorrentDialog = (param.midRef(12).toInt() != 0);
continue; continue;
} }
@ -561,9 +561,7 @@ void Application::processParams(const QStringList &params)
// be shown and skipTorrentDialog is undefined. The other is when // be shown and skipTorrentDialog is undefined. The other is when
// skipTorrentDialog is false, meaning that the application setting // skipTorrentDialog is false, meaning that the application setting
// should be overridden. // should be overridden.
const bool showDialogForThisTorrent = const bool showDialogForThisTorrent = !skipTorrentDialog.value_or(!AddNewTorrentDialog::isEnabled());
((AddNewTorrentDialog::isEnabled() && skipTorrentDialog == TriStateBool::Undefined)
|| skipTorrentDialog == TriStateBool::False);
if (showDialogForThisTorrent) if (showDialogForThisTorrent)
AddNewTorrentDialog::show(param, torrentParams, m_window); AddNewTorrentDialog::show(param, torrentParams, m_window);
else else

40
src/app/cmdoptions.cpp

@ -254,13 +254,13 @@ namespace
return padUsageText(fullParameter() + QLatin1String("=<true|false>")); return padUsageText(fullParameter() + QLatin1String("=<true|false>"));
} }
TriStateBool value(const QString &arg) const std::optional<bool> value(const QString &arg) const
{ {
QStringList parts = arg.split(QLatin1Char('=')); QStringList parts = arg.split(QLatin1Char('='));
if (parts.size() == 1) if (parts.size() == 1)
{ {
return TriStateBool(m_defaultValue); return m_defaultValue;
} }
if (parts.size() == 2) if (parts.size() == 2)
{ {
@ -268,11 +268,11 @@ namespace
if ((val.toUpper() == QLatin1String("TRUE")) || (val == QLatin1String("1"))) if ((val.toUpper() == QLatin1String("TRUE")) || (val == QLatin1String("1")))
{ {
return TriStateBool::True; return true;
} }
if ((val.toUpper() == QLatin1String("FALSE")) || (val == QLatin1String("0"))) if ((val.toUpper() == QLatin1String("FALSE")) || (val == QLatin1String("0")))
{ {
return TriStateBool::False; return false;
} }
} }
@ -282,30 +282,30 @@ namespace
.arg(fullParameter(), QLatin1String("<true|false>"))); .arg(fullParameter(), QLatin1String("<true|false>")));
} }
TriStateBool value(const QProcessEnvironment &env) const std::optional<bool> value(const QProcessEnvironment &env) const
{ {
const QString val = env.value(envVarName(), "-1"); const QString val = env.value(envVarName(), "-1");
if (val.isEmpty()) if (val.isEmpty())
{ {
return TriStateBool(m_defaultValue); return m_defaultValue;
} }
if (val == QLatin1String("-1")) if (val == QLatin1String("-1"))
{ {
return TriStateBool::Undefined; return std::nullopt;
} }
if ((val.toUpper() == QLatin1String("TRUE")) || (val == QLatin1String("1"))) if ((val.toUpper() == QLatin1String("TRUE")) || (val == QLatin1String("1")))
{ {
return TriStateBool::True; return true;
} }
if ((val.toUpper() == QLatin1String("FALSE")) || (val == QLatin1String("0"))) if ((val.toUpper() == QLatin1String("FALSE")) || (val == QLatin1String("0")))
{ {
return TriStateBool::False; return false;
} }
qDebug() << QObject::tr("Expected %1 in environment variable '%2', but got '%3'") qDebug() << QObject::tr("Expected %1 in environment variable '%2', but got '%3'")
.arg(QLatin1String("true|false"), envVarName(), val); .arg(QLatin1String("true|false"), envVarName(), val);
return TriStateBool::Undefined; return std::nullopt;
} }
bool m_defaultValue; bool m_defaultValue;
@ -374,14 +374,8 @@ QStringList QBtCommandLineParameters::paramList() const
if (!savePath.isEmpty()) if (!savePath.isEmpty())
result.append(QLatin1String("@savePath=") + savePath); result.append(QLatin1String("@savePath=") + savePath);
if (addPaused == TriStateBool::True) if (addPaused.has_value())
{ result.append(*addPaused ? QLatin1String {"@addPaused=1"} : QLatin1String {"@addPaused=0"});
result.append(QLatin1String("@addPaused=1"));
}
else if (addPaused == TriStateBool::False)
{
result.append(QLatin1String("@addPaused=0"));
}
if (skipChecking) if (skipChecking)
result.append(QLatin1String("@skipChecking")); result.append(QLatin1String("@skipChecking"));
@ -395,14 +389,8 @@ QStringList QBtCommandLineParameters::paramList() const
if (firstLastPiecePriority) if (firstLastPiecePriority)
result.append(QLatin1String("@firstLastPiecePriority")); result.append(QLatin1String("@firstLastPiecePriority"));
if (skipDialog == TriStateBool::True) if (skipDialog.has_value())
{ result.append(*skipDialog ? QLatin1String {"@skipDialog=1"} : QLatin1String {"@skipDialog=0"});
result.append(QLatin1String("@skipDialog=1"));
}
else if (skipDialog == TriStateBool::False)
{
result.append(QLatin1String("@skipDialog=0"));
}
result += torrents; result += torrents;
return result; return result;

7
src/app/cmdoptions.h

@ -30,13 +30,12 @@
#pragma once #pragma once
#include <optional>
#include <stdexcept> #include <stdexcept>
#include <QString> #include <QString>
#include <QStringList> #include <QStringList>
#include "base/tristatebool.h"
class QProcessEnvironment; class QProcessEnvironment;
struct QBtCommandLineParameters struct QBtCommandLineParameters
@ -55,8 +54,8 @@ struct QBtCommandLineParameters
bool shouldDaemonize; bool shouldDaemonize;
#endif #endif
int webUiPort; int webUiPort;
TriStateBool addPaused; std::optional<bool> addPaused;
TriStateBool skipDialog; std::optional<bool> skipDialog;
QStringList torrents; QStringList torrents;
QString profileDir; QString profileDir;
QString configurationName; QString configurationName;

2
src/base/CMakeLists.txt

@ -73,7 +73,6 @@ add_library(qbt_base STATIC
settingsstorage.h settingsstorage.h
torrentfileguard.h torrentfileguard.h
torrentfilter.h torrentfilter.h
tristatebool.h
types.h types.h
unicodestrings.h unicodestrings.h
utils/bytearray.h utils/bytearray.h
@ -150,7 +149,6 @@ add_library(qbt_base STATIC
settingsstorage.cpp settingsstorage.cpp
torrentfileguard.cpp torrentfileguard.cpp
torrentfilter.cpp torrentfilter.cpp
tristatebool.cpp
utils/bytearray.cpp utils/bytearray.cpp
utils/foreignapps.cpp utils/foreignapps.cpp
utils/fs.cpp utils/fs.cpp

2
src/base/base.pri

@ -73,7 +73,6 @@ HEADERS += \
$$PWD/settingvalue.h \ $$PWD/settingvalue.h \
$$PWD/torrentfileguard.h \ $$PWD/torrentfileguard.h \
$$PWD/torrentfilter.h \ $$PWD/torrentfilter.h \
$$PWD/tristatebool.h \
$$PWD/types.h \ $$PWD/types.h \
$$PWD/unicodestrings.h \ $$PWD/unicodestrings.h \
$$PWD/utils/bytearray.h \ $$PWD/utils/bytearray.h \
@ -150,7 +149,6 @@ SOURCES += \
$$PWD/settingsstorage.cpp \ $$PWD/settingsstorage.cpp \
$$PWD/torrentfileguard.cpp \ $$PWD/torrentfileguard.cpp \
$$PWD/torrentfilter.cpp \ $$PWD/torrentfilter.cpp \
$$PWD/tristatebool.cpp \
$$PWD/utils/bytearray.cpp \ $$PWD/utils/bytearray.cpp \
$$PWD/utils/foreignapps.cpp \ $$PWD/utils/foreignapps.cpp \
$$PWD/utils/fs.cpp \ $$PWD/utils/fs.cpp \

11
src/base/bittorrent/addtorrentparams.h

@ -28,13 +28,12 @@
#pragma once #pragma once
#include <boost/optional.hpp> #include <optional>
#include <QSet> #include <QSet>
#include <QString> #include <QString>
#include <QVector> #include <QVector>
#include "base/tristatebool.h"
#include "torrenthandle.h" #include "torrenthandle.h"
#include "torrentcontentlayout.h" #include "torrentcontentlayout.h"
@ -51,12 +50,12 @@ namespace BitTorrent
bool disableTempPath = false; // e.g. for imported torrents bool disableTempPath = false; // e.g. for imported torrents
bool sequential = false; bool sequential = false;
bool firstLastPiecePriority = false; bool firstLastPiecePriority = false;
TriStateBool addForced; bool addForced = false;
TriStateBool addPaused; std::optional<bool> addPaused;
QVector<DownloadPriority> filePriorities; // used if TorrentInfo is set QVector<DownloadPriority> filePriorities; // used if TorrentInfo is set
bool skipChecking = false; bool skipChecking = false;
boost::optional<BitTorrent::TorrentContentLayout> contentLayout; std::optional<BitTorrent::TorrentContentLayout> contentLayout;
TriStateBool useAutoTMM; std::optional<bool> useAutoTMM;
int uploadLimit = -1; int uploadLimit = -1;
int downloadLimit = -1; int downloadLimit = -1;
int seedingTimeLimit = TorrentHandle::USE_GLOBAL_SEEDING_TIME; int seedingTimeLimit = TorrentHandle::USE_GLOBAL_SEEDING_TIME;

15
src/base/bittorrent/session.cpp

@ -78,7 +78,6 @@
#include "base/profile.h" #include "base/profile.h"
#include "base/torrentfileguard.h" #include "base/torrentfileguard.h"
#include "base/torrentfilter.h" #include "base/torrentfilter.h"
#include "base/tristatebool.h"
#include "base/unicodestrings.h" #include "base/unicodestrings.h"
#include "base/utils/bytearray.h" #include "base/utils/bytearray.h"
#include "base/utils/fs.h" #include "base/utils/fs.h"
@ -2057,19 +2056,13 @@ LoadTorrentParams Session::initLoadTorrentParams(const AddTorrentParams &addTorr
loadTorrentParams.tags = addTorrentParams.tags; loadTorrentParams.tags = addTorrentParams.tags;
loadTorrentParams.firstLastPiecePriority = addTorrentParams.firstLastPiecePriority; loadTorrentParams.firstLastPiecePriority = addTorrentParams.firstLastPiecePriority;
loadTorrentParams.hasSeedStatus = addTorrentParams.skipChecking; // do not react on 'torrent_finished_alert' when skipping loadTorrentParams.hasSeedStatus = addTorrentParams.skipChecking; // do not react on 'torrent_finished_alert' when skipping
loadTorrentParams.contentLayout = (addTorrentParams.contentLayout loadTorrentParams.contentLayout = addTorrentParams.contentLayout.value_or(torrentContentLayout());
? *addTorrentParams.contentLayout loadTorrentParams.forced = addTorrentParams.addForced;
: torrentContentLayout()); loadTorrentParams.paused = addTorrentParams.addPaused.value_or(isAddTorrentPaused());
loadTorrentParams.forced = (addTorrentParams.addForced == TriStateBool::True);
loadTorrentParams.paused = ((addTorrentParams.addPaused == TriStateBool::Undefined)
? isAddTorrentPaused()
: (addTorrentParams.addPaused == TriStateBool::True));
loadTorrentParams.ratioLimit = addTorrentParams.ratioLimit; loadTorrentParams.ratioLimit = addTorrentParams.ratioLimit;
loadTorrentParams.seedingTimeLimit = addTorrentParams.seedingTimeLimit; loadTorrentParams.seedingTimeLimit = addTorrentParams.seedingTimeLimit;
const bool useAutoTMM = ((addTorrentParams.useAutoTMM == TriStateBool::Undefined) const bool useAutoTMM = addTorrentParams.useAutoTMM.value_or(!isAutoTMMDisabledByDefault());
? !isAutoTMMDisabledByDefault()
: (addTorrentParams.useAutoTMM == TriStateBool::True));
if (useAutoTMM) if (useAutoTMM)
loadTorrentParams.savePath = ""; loadTorrentParams.savePath = "";
else if (addTorrentParams.savePath.trimmed().isEmpty()) else if (addTorrentParams.savePath.trimmed().isEmpty())

3
src/base/rss/rss_autodownloader.cpp

@ -47,7 +47,6 @@
#include "../logger.h" #include "../logger.h"
#include "../profile.h" #include "../profile.h"
#include "../settingsstorage.h" #include "../settingsstorage.h"
#include "../tristatebool.h"
#include "../utils/fs.h" #include "../utils/fs.h"
#include "rss_article.h" #include "rss_article.h"
#include "rss_autodownloadrule.h" #include "rss_autodownloadrule.h"
@ -398,7 +397,7 @@ void AutoDownloader::processJob(const QSharedPointer<ProcessingJob> &job)
params.addPaused = rule.addPaused(); params.addPaused = rule.addPaused();
params.contentLayout = rule.torrentContentLayout(); params.contentLayout = rule.torrentContentLayout();
if (!rule.savePath().isEmpty()) if (!rule.savePath().isEmpty())
params.useAutoTMM = TriStateBool::False; params.useAutoTMM = false;
const auto torrentURL = job->articleData.value(Article::KeyTorrentURL).toString(); const auto torrentURL = job->articleData.value(Article::KeyTorrentURL).toString();
BitTorrent::Session::instance()->addTorrent(torrentURL, params); BitTorrent::Session::instance()->addTorrent(torrentURL, params);

82
src/base/rss/rss_autodownloadrule.cpp

@ -42,7 +42,6 @@
#include "base/global.h" #include "base/global.h"
#include "base/preferences.h" #include "base/preferences.h"
#include "base/tristatebool.h"
#include "base/utils/fs.h" #include "base/utils/fs.h"
#include "base/utils/string.h" #include "base/utils/string.h"
#include "rss_article.h" #include "rss_article.h"
@ -51,56 +50,49 @@
namespace namespace
{ {
TriStateBool jsonValueToTriStateBool(const QJsonValue &jsonVal) std::optional<bool> toOptionalBool(const QJsonValue &jsonVal)
{ {
if (jsonVal.isBool()) if (jsonVal.isBool())
return TriStateBool(jsonVal.toBool()); return jsonVal.toBool();
if (!jsonVal.isNull()) return std::nullopt;
qDebug() << Q_FUNC_INFO << "Incorrect value" << jsonVal.toVariant();
return TriStateBool::Undefined;
} }
QJsonValue triStateBoolToJsonValue(const TriStateBool triStateBool) QJsonValue toJsonValue(const std::optional<bool> boolValue)
{
switch (static_cast<signed char>(triStateBool))
{ {
case 0: return false; return boolValue.has_value() ? *boolValue : QJsonValue {};
case 1: return true;
default: return {};
}
} }
TriStateBool addPausedLegacyToTriStateBool(const int val) std::optional<bool> addPausedLegacyToOptionalBool(const int val)
{ {
switch (val) switch (val)
{ {
case 1: return TriStateBool::True; // always case 1:
case 2: return TriStateBool::False; // never return true; // always
default: return TriStateBool::Undefined; // default case 2:
return false; // never
default:
return std::nullopt; // default
} }
} }
int triStateBoolToAddPausedLegacy(const TriStateBool triStateBool) int toAddPausedLegacy(const std::optional<bool> boolValue)
{ {
switch (static_cast<signed char>(triStateBool)) if (!boolValue.has_value())
{ return 0; // default
case 0: return 2; // never
case 1: return 1; // always return (*boolValue ? 1 /* always */ : 2 /* never */);
default: return 0; // default
}
} }
boost::optional<BitTorrent::TorrentContentLayout> jsonValueToContentLayout(const QJsonValue &jsonVal) std::optional<BitTorrent::TorrentContentLayout> jsonValueToContentLayout(const QJsonValue &jsonVal)
{ {
const QString str = jsonVal.toString(); const QString str = jsonVal.toString();
if (str.isEmpty()) if (str.isEmpty())
return {}; return std::nullopt;
return Utils::String::toEnum(str, BitTorrent::TorrentContentLayout::Original); return Utils::String::toEnum(str, BitTorrent::TorrentContentLayout::Original);
} }
QJsonValue contentLayoutToJsonValue(const boost::optional<BitTorrent::TorrentContentLayout> contentLayout) QJsonValue contentLayoutToJsonValue(const std::optional<BitTorrent::TorrentContentLayout> contentLayout)
{ {
if (!contentLayout) if (!contentLayout)
return {}; return {};
@ -142,8 +134,8 @@ namespace RSS
QString savePath; QString savePath;
QString category; QString category;
TriStateBool addPaused = TriStateBool::Undefined; std::optional<bool> addPaused;
boost::optional<BitTorrent::TorrentContentLayout> contentLayout; std::optional<BitTorrent::TorrentContentLayout> contentLayout;
bool smartFilter = false; bool smartFilter = false;
QStringList previouslyMatchedEpisodes; QStringList previouslyMatchedEpisodes;
@ -477,7 +469,7 @@ QJsonObject AutoDownloadRule::toJsonObject() const
, {Str_AssignedCategory, assignedCategory()} , {Str_AssignedCategory, assignedCategory()}
, {Str_LastMatch, lastMatch().toString(Qt::RFC2822Date)} , {Str_LastMatch, lastMatch().toString(Qt::RFC2822Date)}
, {Str_IgnoreDays, ignoreDays()} , {Str_IgnoreDays, ignoreDays()}
, {Str_AddPaused, triStateBoolToJsonValue(addPaused())} , {Str_AddPaused, toJsonValue(addPaused())}
, {Str_ContentLayout, contentLayoutToJsonValue(torrentContentLayout())} , {Str_ContentLayout, contentLayoutToJsonValue(torrentContentLayout())}
, {Str_SmartFilter, useSmartFilter()} , {Str_SmartFilter, useSmartFilter()}
, {Str_PreviouslyMatched, QJsonArray::fromStringList(previouslyMatchedEpisodes())}}; , {Str_PreviouslyMatched, QJsonArray::fromStringList(previouslyMatchedEpisodes())}};
@ -494,7 +486,7 @@ AutoDownloadRule AutoDownloadRule::fromJsonObject(const QJsonObject &jsonObj, co
rule.setEnabled(jsonObj.value(Str_Enabled).toBool(true)); rule.setEnabled(jsonObj.value(Str_Enabled).toBool(true));
rule.setSavePath(jsonObj.value(Str_SavePath).toString()); rule.setSavePath(jsonObj.value(Str_SavePath).toString());
rule.setCategory(jsonObj.value(Str_AssignedCategory).toString()); rule.setCategory(jsonObj.value(Str_AssignedCategory).toString());
rule.setAddPaused(jsonValueToTriStateBool(jsonObj.value(Str_AddPaused))); rule.setAddPaused(toOptionalBool(jsonObj.value(Str_AddPaused)));
// TODO: The following code is deprecated. Replace with the commented one after several releases in 4.4.x. // TODO: The following code is deprecated. Replace with the commented one after several releases in 4.4.x.
// === BEGIN DEPRECATED CODE === // // === BEGIN DEPRECATED CODE === //
@ -504,12 +496,14 @@ AutoDownloadRule AutoDownloadRule::fromJsonObject(const QJsonObject &jsonObj, co
} }
else else
{ {
const TriStateBool createSubfolder = jsonValueToTriStateBool(jsonObj.value(Str_CreateSubfolder)); const std::optional<bool> createSubfolder = toOptionalBool(jsonObj.value(Str_CreateSubfolder));
boost::optional<BitTorrent::TorrentContentLayout> contentLayout; std::optional<BitTorrent::TorrentContentLayout> contentLayout;
if (createSubfolder == TriStateBool::True) if (createSubfolder.has_value())
contentLayout = BitTorrent::TorrentContentLayout::Original; {
else if (createSubfolder == TriStateBool::False) contentLayout = (*createSubfolder
contentLayout = BitTorrent::TorrentContentLayout::NoSubfolder; ? BitTorrent::TorrentContentLayout::Original
: BitTorrent::TorrentContentLayout::NoSubfolder);
}
rule.setTorrentContentLayout(contentLayout); rule.setTorrentContentLayout(contentLayout);
} }
@ -556,7 +550,7 @@ QVariantHash AutoDownloadRule::toLegacyDict() const
{"enabled", isEnabled()}, {"enabled", isEnabled()},
{"category_assigned", assignedCategory()}, {"category_assigned", assignedCategory()},
{"use_regex", useRegex()}, {"use_regex", useRegex()},
{"add_paused", triStateBoolToAddPausedLegacy(addPaused())}, {"add_paused", toAddPausedLegacy(addPaused())},
{"episode_filter", episodeFilter()}, {"episode_filter", episodeFilter()},
{"last_match", lastMatch()}, {"last_match", lastMatch()},
{"ignore_days", ignoreDays()}}; {"ignore_days", ignoreDays()}};
@ -574,7 +568,7 @@ AutoDownloadRule AutoDownloadRule::fromLegacyDict(const QVariantHash &dict)
rule.setEnabled(dict.value("enabled", false).toBool()); rule.setEnabled(dict.value("enabled", false).toBool());
rule.setSavePath(dict.value("save_path").toString()); rule.setSavePath(dict.value("save_path").toString());
rule.setCategory(dict.value("category_assigned").toString()); rule.setCategory(dict.value("category_assigned").toString());
rule.setAddPaused(addPausedLegacyToTriStateBool(dict.value("add_paused").toInt())); rule.setAddPaused(addPausedLegacyToOptionalBool(dict.value("add_paused").toInt()));
rule.setLastMatch(dict.value("last_match").toDateTime()); rule.setLastMatch(dict.value("last_match").toDateTime());
rule.setIgnoreDays(dict.value("ignore_days").toInt()); rule.setIgnoreDays(dict.value("ignore_days").toInt());
@ -639,22 +633,22 @@ void AutoDownloadRule::setSavePath(const QString &savePath)
m_dataPtr->savePath = Utils::Fs::toUniformPath(savePath); m_dataPtr->savePath = Utils::Fs::toUniformPath(savePath);
} }
TriStateBool AutoDownloadRule::addPaused() const std::optional<bool> AutoDownloadRule::addPaused() const
{ {
return m_dataPtr->addPaused; return m_dataPtr->addPaused;
} }
void AutoDownloadRule::setAddPaused(const TriStateBool addPaused) void AutoDownloadRule::setAddPaused(const std::optional<bool> addPaused)
{ {
m_dataPtr->addPaused = addPaused; m_dataPtr->addPaused = addPaused;
} }
boost::optional<BitTorrent::TorrentContentLayout> AutoDownloadRule::torrentContentLayout() const std::optional<BitTorrent::TorrentContentLayout> AutoDownloadRule::torrentContentLayout() const
{ {
return m_dataPtr->contentLayout; return m_dataPtr->contentLayout;
} }
void AutoDownloadRule::setTorrentContentLayout(const boost::optional<BitTorrent::TorrentContentLayout> contentLayout) void AutoDownloadRule::setTorrentContentLayout(const std::optional<BitTorrent::TorrentContentLayout> contentLayout)
{ {
m_dataPtr->contentLayout = contentLayout; m_dataPtr->contentLayout = contentLayout;
} }

12
src/base/rss/rss_autodownloadrule.h

@ -29,7 +29,7 @@
#pragma once #pragma once
#include <boost/optional.hpp> #include <optional>
#include <QSharedDataPointer> #include <QSharedDataPointer>
#include <QVariant> #include <QVariant>
@ -40,8 +40,6 @@ class QDateTime;
class QJsonObject; class QJsonObject;
class QRegularExpression; class QRegularExpression;
class TriStateBool;
namespace RSS namespace RSS
{ {
struct AutoDownloadRuleData; struct AutoDownloadRuleData;
@ -81,10 +79,10 @@ namespace RSS
QString savePath() const; QString savePath() const;
void setSavePath(const QString &savePath); void setSavePath(const QString &savePath);
TriStateBool addPaused() const; std::optional<bool> addPaused() const;
void setAddPaused(TriStateBool addPaused); void setAddPaused(std::optional<bool> addPaused);
boost::optional<BitTorrent::TorrentContentLayout> torrentContentLayout() const; std::optional<BitTorrent::TorrentContentLayout> torrentContentLayout() const;
void setTorrentContentLayout(boost::optional<BitTorrent::TorrentContentLayout> contentLayout); void setTorrentContentLayout(std::optional<BitTorrent::TorrentContentLayout> contentLayout);
QString assignedCategory() const; QString assignedCategory() const;
void setCategory(const QString &category); void setCategory(const QString &category);

4
src/base/scanfoldersmodel.cpp

@ -366,12 +366,12 @@ void ScanFoldersModel::addTorrentsToSession(const QStringList &pathList)
if (downloadInWatchFolder(file)) if (downloadInWatchFolder(file))
{ {
params.savePath = QFileInfo(file).dir().path(); params.savePath = QFileInfo(file).dir().path();
params.useAutoTMM = TriStateBool::False; params.useAutoTMM = false;
} }
else if (!downloadInDefaultFolder(file)) else if (!downloadInDefaultFolder(file))
{ {
params.savePath = downloadPathTorrentFolder(file); params.savePath = downloadPathTorrentFolder(file);
params.useAutoTMM = TriStateBool::False; params.useAutoTMM = false;
} }
if (file.endsWith(".magnet", Qt::CaseInsensitive)) if (file.endsWith(".magnet", Qt::CaseInsensitive))

44
src/base/tristatebool.cpp

@ -1,44 +0,0 @@
/*
* Bittorrent Client using Qt and libtorrent.
* Copyright (C) 2015 Vladimir Golovnev <glassez@yandex.ru>
*
* 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 "tristatebool.h"
#include <QString>
const TriStateBool TriStateBool::Undefined(-1);
const TriStateBool TriStateBool::False(0);
const TriStateBool TriStateBool::True(1);
TriStateBool TriStateBool::fromString(const QString &string)
{
if (string.compare("true", Qt::CaseInsensitive) == 0)
return True;
if (string.compare("false", Qt::CaseInsensitive) == 0)
return False;
return Undefined;
}

73
src/base/tristatebool.h

@ -1,73 +0,0 @@
/*
* Bittorrent Client using Qt and libtorrent.
* Copyright (C) 2015 Vladimir Golovnev <glassez@yandex.ru>
*
* 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.
*/
#pragma once
class QString;
class TriStateBool
{
public:
static const TriStateBool Undefined;
static const TriStateBool False;
static const TriStateBool True;
constexpr TriStateBool() = default;
constexpr TriStateBool(const TriStateBool &other) = default;
explicit constexpr TriStateBool(const bool boolean)
{
*this = boolean ? True : False;
}
constexpr TriStateBool &operator=(const TriStateBool &other) = default;
explicit constexpr operator signed char() const
{
return m_value;
}
constexpr friend bool operator==(const TriStateBool &left, const TriStateBool &right)
{
return (left.m_value == right.m_value);
}
static TriStateBool fromString(const QString &string);
private:
explicit constexpr TriStateBool(const int value)
: m_value((value < 0) ? -1 : ((value > 0) ? 1 : 0))
{
}
signed char m_value = -1; // Undefined by default
};
constexpr bool operator!=(const TriStateBool &left, const TriStateBool &right)
{
return !(left == right);
}

11
src/base/utils/string.cpp

@ -190,11 +190,14 @@ QString Utils::String::wildcardToRegex(const QString &pattern)
return qt_regexp_toCanonical(pattern, QRegExp::Wildcard); return qt_regexp_toCanonical(pattern, QRegExp::Wildcard);
} }
bool Utils::String::parseBool(const QString &string, const bool defaultValue) std::optional<bool> Utils::String::parseBool(const QString &string)
{ {
if (defaultValue) if (string.compare("true", Qt::CaseInsensitive) == 0)
return (string.compare("false", Qt::CaseInsensitive) == 0) ? false : true; return true;
return (string.compare("true", Qt::CaseInsensitive) == 0) ? true : false; if (string.compare("false", Qt::CaseInsensitive) == 0)
return false;
return std::nullopt;
} }
QString Utils::String::join(const QVector<QStringRef> &strings, const QString &separator) QString Utils::String::join(const QVector<QStringRef> &strings, const QString &separator)

4
src/base/utils/string.h

@ -29,6 +29,8 @@
#pragma once #pragma once
#include <optional>
#include <QChar> #include <QChar>
#include <QMetaEnum> #include <QMetaEnum>
#include <QString> #include <QString>
@ -64,7 +66,7 @@ namespace Utils::String
return str; return str;
} }
bool parseBool(const QString &string, bool defaultValue); std::optional<bool> parseBool(const QString &string);
QString join(const QVector<QStringRef> &strings, const QString &separator); QString join(const QVector<QStringRef> &strings, const QString &separator);

15
src/gui/addnewtorrentdialog.cpp

@ -107,12 +107,7 @@ AddNewTorrentDialog::AddNewTorrentDialog(const BitTorrent::AddTorrentParams &inP
const auto *session = BitTorrent::Session::instance(); const auto *session = BitTorrent::Session::instance();
if (m_torrentParams.addPaused == TriStateBool::True) m_ui->startTorrentCheckBox->setChecked(!m_torrentParams.addPaused.value_or(session->isAddTorrentPaused()));
m_ui->startTorrentCheckBox->setChecked(false);
else if (m_torrentParams.addPaused == TriStateBool::False)
m_ui->startTorrentCheckBox->setChecked(true);
else
m_ui->startTorrentCheckBox->setChecked(!session->isAddTorrentPaused());
m_ui->comboTTM->blockSignals(true); // the TreeView size isn't correct if the slot does it job at this point m_ui->comboTTM->blockSignals(true); // the TreeView size isn't correct if the slot does it job at this point
m_ui->comboTTM->setCurrentIndex(!session->isAutoTMMDisabledByDefault()); m_ui->comboTTM->setCurrentIndex(!session->isAutoTMMDisabledByDefault());
@ -124,7 +119,7 @@ AddNewTorrentDialog::AddNewTorrentDialog(const BitTorrent::AddTorrentParams &inP
m_ui->checkBoxRememberLastSavePath->setChecked(rememberLastSavePath); m_ui->checkBoxRememberLastSavePath->setChecked(rememberLastSavePath);
m_ui->contentLayoutComboBox->setCurrentIndex( m_ui->contentLayoutComboBox->setCurrentIndex(
static_cast<int>(m_torrentParams.contentLayout ? *m_torrentParams.contentLayout : session->torrentContentLayout())); static_cast<int>(m_torrentParams.contentLayout.value_or(session->torrentContentLayout())));
m_ui->sequentialCheckBox->setChecked(m_torrentParams.sequential); m_ui->sequentialCheckBox->setChecked(m_torrentParams.sequential);
m_ui->firstLastCheckBox->setChecked(m_torrentParams.firstLastPiecePriority); m_ui->firstLastCheckBox->setChecked(m_torrentParams.firstLastPiecePriority);
@ -573,7 +568,7 @@ void AddNewTorrentDialog::accept()
if (m_contentModel) if (m_contentModel)
m_torrentParams.filePriorities = m_contentModel->model()->getFilePriorities(); m_torrentParams.filePriorities = m_contentModel->model()->getFilePriorities();
m_torrentParams.addPaused = TriStateBool(!m_ui->startTorrentCheckBox->isChecked()); m_torrentParams.addPaused = !m_ui->startTorrentCheckBox->isChecked();
m_torrentParams.contentLayout = static_cast<BitTorrent::TorrentContentLayout>(m_ui->contentLayoutComboBox->currentIndex()); m_torrentParams.contentLayout = static_cast<BitTorrent::TorrentContentLayout>(m_ui->contentLayoutComboBox->currentIndex());
m_torrentParams.sequential = m_ui->sequentialCheckBox->isChecked(); m_torrentParams.sequential = m_ui->sequentialCheckBox->isChecked();
@ -582,13 +577,13 @@ void AddNewTorrentDialog::accept()
QString savePath = m_ui->savePath->selectedPath(); QString savePath = m_ui->savePath->selectedPath();
if (m_ui->comboTTM->currentIndex() != 1) if (m_ui->comboTTM->currentIndex() != 1)
{ // 0 is Manual mode and 1 is Automatic mode. Handle all non 1 values as manual mode. { // 0 is Manual mode and 1 is Automatic mode. Handle all non 1 values as manual mode.
m_torrentParams.useAutoTMM = TriStateBool::False; m_torrentParams.useAutoTMM = false;
m_torrentParams.savePath = savePath; m_torrentParams.savePath = savePath;
saveSavePathHistory(); saveSavePathHistory();
} }
else else
{ {
m_torrentParams.useAutoTMM = TriStateBool::True; m_torrentParams.useAutoTMM = true;
} }
setEnabled(!m_ui->checkBoxNeverShow->isChecked()); setEnabled(!m_ui->checkBoxNeverShow->isChecked());

14
src/gui/rss/automatedrssdownloader.cpp

@ -269,10 +269,8 @@ void AutomatedRssDownloader::updateRuleDefinitionBox()
if (m_currentRule.assignedCategory().isEmpty()) if (m_currentRule.assignedCategory().isEmpty())
m_ui->comboCategory->clearEditText(); m_ui->comboCategory->clearEditText();
int index = 0; int index = 0;
if (m_currentRule.addPaused() == TriStateBool::True) if (m_currentRule.addPaused().has_value())
index = 1; index = (*m_currentRule.addPaused() ? 1 : 2);
else if (m_currentRule.addPaused() == TriStateBool::False)
index = 2;
m_ui->comboAddPaused->setCurrentIndex(index); m_ui->comboAddPaused->setCurrentIndex(index);
index = 0; index = 0;
if (m_currentRule.torrentContentLayout()) if (m_currentRule.torrentContentLayout())
@ -347,14 +345,14 @@ void AutomatedRssDownloader::updateEditedRule()
m_currentRule.setEpisodeFilter(m_ui->lineEFilter->text()); m_currentRule.setEpisodeFilter(m_ui->lineEFilter->text());
m_currentRule.setSavePath(m_ui->checkBoxSaveDiffDir->isChecked() ? m_ui->lineSavePath->selectedPath() : ""); m_currentRule.setSavePath(m_ui->checkBoxSaveDiffDir->isChecked() ? m_ui->lineSavePath->selectedPath() : "");
m_currentRule.setCategory(m_ui->comboCategory->currentText()); m_currentRule.setCategory(m_ui->comboCategory->currentText());
TriStateBool addPaused; // Undefined by default std::optional<bool> addPaused;
if (m_ui->comboAddPaused->currentIndex() == 1) if (m_ui->comboAddPaused->currentIndex() == 1)
addPaused = TriStateBool::True; addPaused = true;
else if (m_ui->comboAddPaused->currentIndex() == 2) else if (m_ui->comboAddPaused->currentIndex() == 2)
addPaused = TriStateBool::False; addPaused = false;
m_currentRule.setAddPaused(addPaused); m_currentRule.setAddPaused(addPaused);
boost::optional<BitTorrent::TorrentContentLayout> contentLayout; std::optional<BitTorrent::TorrentContentLayout> contentLayout;
if (m_ui->comboContentLayout->currentIndex() > 0) if (m_ui->comboContentLayout->currentIndex() > 0)
contentLayout = static_cast<BitTorrent::TorrentContentLayout>(m_ui->comboContentLayout->currentIndex() - 1); contentLayout = static_cast<BitTorrent::TorrentContentLayout>(m_ui->comboContentLayout->currentIndex() - 1);
m_currentRule.setTorrentContentLayout(contentLayout); m_currentRule.setTorrentContentLayout(contentLayout);

2
src/gui/torrentcreatordialog.cpp

@ -249,7 +249,7 @@ void TorrentCreatorDialog::handleCreationSuccess(const QString &path, const QStr
params.ratioLimit = BitTorrent::TorrentHandle::NO_RATIO_LIMIT; params.ratioLimit = BitTorrent::TorrentHandle::NO_RATIO_LIMIT;
params.seedingTimeLimit = BitTorrent::TorrentHandle::NO_SEEDING_TIME_LIMIT; params.seedingTimeLimit = BitTorrent::TorrentHandle::NO_SEEDING_TIME_LIMIT;
} }
params.useAutoTMM = TriStateBool::False; // otherwise if it is on by default, it will overwrite `savePath` to the default save path params.useAutoTMM = false; // otherwise if it is on by default, it will overwrite `savePath` to the default save path
BitTorrent::Session::instance()->addTorrent(info, params); BitTorrent::Session::instance()->addTorrent(info, params);
} }

8
src/webui/api/logcontroller.cpp

@ -61,10 +61,10 @@ void LogController::mainAction()
{ {
using Utils::String::parseBool; using Utils::String::parseBool;
const bool isNormal = parseBool(params()["normal"], true); const bool isNormal = parseBool(params()["normal"]).value_or(true);
const bool isInfo = parseBool(params()["info"], true); const bool isInfo = parseBool(params()["info"]).value_or(true);
const bool isWarning = parseBool(params()["warning"], true); const bool isWarning = parseBool(params()["warning"]).value_or(true);
const bool isCritical = parseBool(params()["critical"], true); const bool isCritical = parseBool(params()["critical"]).value_or(true);
bool ok = false; bool ok = false;
int lastKnownId = params()["last_known_id"].toInt(&ok); int lastKnownId = params()["last_known_id"].toInt(&ok);

2
src/webui/api/rsscontroller.cpp

@ -89,7 +89,7 @@ void RSSController::moveItemAction()
void RSSController::itemsAction() void RSSController::itemsAction()
{ {
const bool withData {parseBool(params()["withData"], false)}; const bool withData {parseBool(params()["withData"]).value_or(false)};
const auto jsonVal = RSS::Session::instance()->rootFolder()->toJsonValue(withData); const auto jsonVal = RSS::Session::instance()->rootFolder()->toJsonValue(withData);
setResult(jsonVal.toObject()); setResult(jsonVal.toObject());

2
src/webui/api/searchcontroller.cpp

@ -264,7 +264,7 @@ void SearchController::enablePluginAction()
requireParams({"names", "enable"}); requireParams({"names", "enable"});
const QStringList names = params()["names"].split('|'); const QStringList names = params()["names"].split('|');
const bool enable = Utils::String::parseBool(params()["enable"].trimmed(), false); const bool enable = Utils::String::parseBool(params()["enable"].trimmed()).value_or(false);
for (const QString &name : names) for (const QString &name : names)
SearchPluginManager::instance()->enablePlugin(name.trimmed(), enable); SearchPluginManager::instance()->enablePlugin(name.trimmed(), enable);

26
src/webui/api/torrentscontroller.cpp

@ -52,7 +52,6 @@
#include "base/logger.h" #include "base/logger.h"
#include "base/net/downloadmanager.h" #include "base/net/downloadmanager.h"
#include "base/torrentfilter.h" #include "base/torrentfilter.h"
#include "base/tristatebool.h"
#include "base/utils/fs.h" #include "base/utils/fs.h"
#include "base/utils/string.h" #include "base/utils/string.h"
#include "apierror.h" #include "apierror.h"
@ -253,7 +252,7 @@ void TorrentsController::infoAction()
const QString filter {params()["filter"]}; const QString filter {params()["filter"]};
const QString category {params()["category"]}; const QString category {params()["category"]};
const QString sortedColumn {params()["sort"]}; const QString sortedColumn {params()["sort"]};
const bool reverse {parseBool(params()["reverse"], false)}; const bool reverse {parseBool(params()["reverse"]).value_or(false)};
int limit {params()["limit"].toInt()}; int limit {params()["limit"].toInt()};
int offset {params()["offset"].toInt()}; int offset {params()["offset"].toInt()};
const QStringList hashes {params()["hashes"].split('|', QString::SkipEmptyParts)}; const QStringList hashes {params()["hashes"].split('|', QString::SkipEmptyParts)};
@ -601,11 +600,10 @@ void TorrentsController::pieceStatesAction()
void TorrentsController::addAction() void TorrentsController::addAction()
{ {
const QString urls = params()["urls"]; const QString urls = params()["urls"];
const bool skipChecking = parseBool(params()["skip_checking"]).value_or(false);
const bool skipChecking = parseBool(params()["skip_checking"], false); const bool seqDownload = parseBool(params()["sequentialDownload"]).value_or(false);
const bool seqDownload = parseBool(params()["sequentialDownload"], false); const bool firstLastPiece = parseBool(params()["firstLastPiecePrio"]).value_or(false);
const bool firstLastPiece = parseBool(params()["firstLastPiecePrio"], false); const std::optional<bool> addPaused = parseBool(params()["paused"]);
const auto addPaused = TriStateBool::fromString(params()["paused"]);
const QString savepath = params()["savepath"].trimmed(); const QString savepath = params()["savepath"].trimmed();
const QString category = params()["category"]; const QString category = params()["category"];
const QSet<QString> tags = List::toSet(params()["tags"].split(',', QString::SkipEmptyParts)); const QSet<QString> tags = List::toSet(params()["tags"].split(',', QString::SkipEmptyParts));
@ -613,12 +611,12 @@ void TorrentsController::addAction()
const QString torrentName = params()["rename"].trimmed(); const QString torrentName = params()["rename"].trimmed();
const int upLimit = params()["upLimit"].toInt(); const int upLimit = params()["upLimit"].toInt();
const int dlLimit = params()["dlLimit"].toInt(); const int dlLimit = params()["dlLimit"].toInt();
const auto autoTMM = TriStateBool::fromString(params()["autoTMM"]); const std::optional<bool> autoTMM = parseBool(params()["autoTMM"]);
const QString contentLayoutParam = params()["contentLayout"]; const QString contentLayoutParam = params()["contentLayout"];
const boost::optional<BitTorrent::TorrentContentLayout> contentLayout = (!contentLayoutParam.isEmpty() const std::optional<BitTorrent::TorrentContentLayout> contentLayout = (!contentLayoutParam.isEmpty()
? Utils::String::toEnum(contentLayoutParam, BitTorrent::TorrentContentLayout::Original) ? Utils::String::toEnum(contentLayoutParam, BitTorrent::TorrentContentLayout::Original)
: boost::optional<BitTorrent::TorrentContentLayout> {}); : std::optional<BitTorrent::TorrentContentLayout> {});
QList<QNetworkCookie> cookies; QList<QNetworkCookie> cookies;
if (!cookie.isEmpty()) if (!cookie.isEmpty())
@ -962,7 +960,7 @@ void TorrentsController::setSuperSeedingAction()
{ {
requireParams({"hashes", "value"}); requireParams({"hashes", "value"});
const bool value {parseBool(params()["value"], false)}; const bool value {parseBool(params()["value"]).value_or(false)};
const QStringList hashes {params()["hashes"].split('|')}; const QStringList hashes {params()["hashes"].split('|')};
applyToTorrents(hashes, [value](BitTorrent::TorrentHandle *const torrent) { torrent->setSuperSeeding(value); }); applyToTorrents(hashes, [value](BitTorrent::TorrentHandle *const torrent) { torrent->setSuperSeeding(value); });
} }
@ -971,7 +969,7 @@ void TorrentsController::setForceStartAction()
{ {
requireParams({"hashes", "value"}); requireParams({"hashes", "value"});
const bool value {parseBool(params()["value"], false)}; const bool value {parseBool(params()["value"]).value_or(false)};
const QStringList hashes {params()["hashes"].split('|')}; const QStringList hashes {params()["hashes"].split('|')};
applyToTorrents(hashes, [value](BitTorrent::TorrentHandle *const torrent) applyToTorrents(hashes, [value](BitTorrent::TorrentHandle *const torrent)
{ {
@ -984,7 +982,7 @@ void TorrentsController::deleteAction()
requireParams({"hashes", "deleteFiles"}); requireParams({"hashes", "deleteFiles"});
const QStringList hashes {params()["hashes"].split('|')}; const QStringList hashes {params()["hashes"].split('|')};
const DeleteOption deleteOption = parseBool(params()["deleteFiles"], false) const DeleteOption deleteOption = parseBool(params()["deleteFiles"]).value_or(false)
? TorrentAndFiles : Torrent; ? TorrentAndFiles : Torrent;
applyToTorrents(hashes, [deleteOption](const BitTorrent::TorrentHandle *torrent) applyToTorrents(hashes, [deleteOption](const BitTorrent::TorrentHandle *torrent)
{ {
@ -1085,7 +1083,7 @@ void TorrentsController::setAutoManagementAction()
requireParams({"hashes", "enable"}); requireParams({"hashes", "enable"});
const QStringList hashes {params()["hashes"].split('|')}; const QStringList hashes {params()["hashes"].split('|')};
const bool isEnabled {parseBool(params()["enable"], false)}; const bool isEnabled {parseBool(params()["enable"]).value_or(false)};
applyToTorrents(hashes, [isEnabled](BitTorrent::TorrentHandle *const torrent) applyToTorrents(hashes, [isEnabled](BitTorrent::TorrentHandle *const torrent)
{ {

Loading…
Cancel
Save