Revise legal notice

For GUI and non-daemon console, the legal notice won't ask for user acceptance anymore and only
provide an OK button (or Enter key in console) from now on.
For daemon mode, qbt will print the legal notice and continue to run. It will also notify user
to use command line option `--confirm-legal-notice` to suppress the message. The message will be
printed on every start up unless user specify the command line option once.

PR #20080.
This commit is contained in:
Chocobo1 2023-12-05 03:13:37 +08:00 committed by GitHub
parent 608efc77e8
commit 0dbac78e17
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 169 additions and 93 deletions

View file

@ -38,6 +38,7 @@ target_sources(qbt_app PRIVATE
applicationinstancemanager.h
cmdoptions.h
filelogger.h
legalnotice.h
qtlocalpeer/qtlocalpeer.h
signalhandler.h
upgrade.h
@ -47,6 +48,7 @@ target_sources(qbt_app PRIVATE
applicationinstancemanager.cpp
cmdoptions.cpp
filelogger.cpp
legalnotice.cpp
main.cpp
qtlocalpeer/qtlocalpeer.cpp
signalhandler.cpp

View file

@ -57,7 +57,6 @@
#include <QProgressDialog>
#ifdef Q_OS_WIN
#include <QSessionManager>
#include <QSharedMemory>
#endif // Q_OS_WIN
#ifdef Q_OS_MACOS
#include <QFileOpenEvent>
@ -92,7 +91,6 @@
#include "upgrade.h"
#ifndef DISABLE_GUI
#include "gui/guiaddtorrentmanager.h"
#include "gui/desktopintegration.h"
#include "gui/mainwindow.h"
#include "gui/shutdownconfirmdialog.h"
@ -271,17 +269,18 @@ Application::Application(int &argc, char **argv)
SettingsStorage::initInstance();
Preferences::initInstance();
const bool firstTimeUser = !Preferences::instance()->getAcceptedLegal();
if (!firstTimeUser)
const bool firstTimeUser = SettingsStorage::instance()->isEmpty();
if (firstTimeUser)
{
setCurrentMigrationVersion();
handleChangedDefaults(DefaultPreferencesMode::Current);
}
else
{
if (!upgrade())
throw RuntimeError(u"Failed migration of old settings"_s); // Not translatable. Translation isn't configured yet.
handleChangedDefaults(DefaultPreferencesMode::Legacy);
}
else
{
handleChangedDefaults(DefaultPreferencesMode::Current);
}
initializeTranslation();

View file

@ -302,7 +302,10 @@ namespace
};
constexpr const BoolOption SHOW_HELP_OPTION {"help", 'h'};
#if !defined(Q_OS_WIN) || defined(DISABLE_GUI)
constexpr const BoolOption SHOW_VERSION_OPTION {"version", 'v'};
#endif
constexpr const BoolOption CONFIRM_LEGAL_NOTICE {"confirm-legal-notice"};
#if defined(DISABLE_GUI) && !defined(Q_OS_WIN)
constexpr const BoolOption DAEMON_OPTION {"daemon", 'd'};
#else
@ -323,7 +326,8 @@ namespace
}
QBtCommandLineParameters::QBtCommandLineParameters(const QProcessEnvironment &env)
: relativeFastresumePaths(RELATIVE_FASTRESUME.value(env))
: confirmLegalNotice(CONFIRM_LEGAL_NOTICE.value(env))
, relativeFastresumePaths(RELATIVE_FASTRESUME.value(env))
#ifndef DISABLE_GUI
, noSplash(NO_SPLASH_OPTION.value(env))
#elif !defined(Q_OS_WIN)
@ -365,6 +369,10 @@ QBtCommandLineParameters parseCommandLine(const QStringList &args)
result.showVersion = true;
}
#endif
else if (arg == CONFIRM_LEGAL_NOTICE)
{
result.confirmLegalNotice = true;
}
else if (arg == WEBUI_PORT_OPTION)
{
result.webUIPort = WEBUI_PORT_OPTION.value(arg);
@ -484,10 +492,11 @@ QString makeUsage(const QString &prgName)
+ indentation + prgName + u' ' + QCoreApplication::translate("CMD Options", "[options] [(<filename> | <url>)...]") + u'\n'
+ QCoreApplication::translate("CMD Options", "Options:") + u'\n'
+ SHOW_HELP_OPTION.usage() + wrapText(QCoreApplication::translate("CMD Options", "Display this help message and exit")) + u'\n'
#if !defined(Q_OS_WIN) || defined(DISABLE_GUI)
+ SHOW_VERSION_OPTION.usage() + wrapText(QCoreApplication::translate("CMD Options", "Display program version and exit")) + u'\n'
#endif
+ SHOW_HELP_OPTION.usage() + wrapText(QCoreApplication::translate("CMD Options", "Display this help message and exit")) + u'\n'
+ CONFIRM_LEGAL_NOTICE.usage() + wrapText(QCoreApplication::translate("CMD Options", "Confirm the legal notice")) + u'\n'
+ WEBUI_PORT_OPTION.usage(QCoreApplication::translate("CMD Options", "port"))
+ wrapText(QCoreApplication::translate("CMD Options", "Change the WebUI port"))
+ u'\n'

View file

@ -44,10 +44,11 @@ class QProcessEnvironment;
struct QBtCommandLineParameters
{
bool showHelp = false;
bool relativeFastresumePaths = false;
#if !defined(Q_OS_WIN) || defined(DISABLE_GUI)
bool showVersion = false;
#endif
bool confirmLegalNotice = false;
bool relativeFastresumePaths = false;
#ifndef DISABLE_GUI
bool noSplash = false;
#elif !defined(Q_OS_WIN)

77
src/app/legalnotice.cpp Normal file
View file

@ -0,0 +1,77 @@
/*
* Bittorrent Client using Qt and libtorrent.
* Copyright (C) 2023 Mike Tzou (Chocobo1)
*
* 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 "legalnotice.h"
#ifdef DISABLE_GUI
#include <cstdio>
#endif // DISABLE_GUI
#include <QCoreApplication>
#include <QString>
#ifndef DISABLE_GUI
#include <QMessageBox>
#endif // DISABLE_GUI
#include "base/global.h"
#ifndef DISABLE_GUI
#include "gui/utils.h"
#endif // DISABLE_GUI
void showLegalNotice(const bool isInteractive)
{
const QString noticeTitle = QCoreApplication::translate("LegalNotice", "Legal Notice");
const QString noticeBody = QCoreApplication::translate("LegalNotice", "qBittorrent is a file sharing program. When you run a torrent, its data will be made available to others by means of upload. Any content you share is your sole responsibility.");
const QString noticeEnd = QCoreApplication::translate("LegalNotice", "No further notices will be issued.");
if (!isInteractive)
{
const QString legalNotice = u"\n*** %1 ***\n"_s.arg(noticeTitle)
+ noticeBody + u"\n\n"
+ QCoreApplication::translate("LegalNotice", "If you have read the legal notice, you can use command line option `--confirm-legal-notice` to suppress this message.");
printf("%s\n\n", qUtf8Printable(legalNotice));
return;
}
#ifdef DISABLE_GUI
const QString legalNotice = u"\n*** %1 ***\n"_s.arg(noticeTitle)
+ noticeBody + u"\n\n"
+ noticeEnd + u"\n\n"
+ QCoreApplication::translate("LegalNotice", "Press 'Enter' key to continue...");
printf("%s", qUtf8Printable(legalNotice));
getchar();
#else // DISABLE_GUI
const QString messageBody = noticeBody + u"\n\n" + noticeEnd;
QMessageBox msgBox {QMessageBox::NoIcon, noticeTitle, messageBody, QMessageBox::Ok};
msgBox.show(); // Need to be shown first or moveToCenter does not work
msgBox.move(Utils::Gui::screenCenter(&msgBox));
msgBox.exec();
#endif // DISABLE_GUI
}

31
src/app/legalnotice.h Normal file
View file

@ -0,0 +1,31 @@
/*
* Bittorrent Client using Qt and libtorrent.
* Copyright (C) 2023 Mike Tzou (Chocobo1)
*
* 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
void showLegalNotice(bool isInteractive);

View file

@ -55,7 +55,6 @@
#include <QMessageBox>
#include <QPainter>
#include <QPen>
#include <QPushButton>
#include <QSplashScreen>
#include <QTimer>
@ -76,11 +75,12 @@ Q_IMPORT_PLUGIN(QICOPlugin)
#include "base/logger.h"
#include "base/preferences.h"
#include "base/profile.h"
#include "base/settingvalue.h"
#include "base/version.h"
#include "application.h"
#include "cmdoptions.h"
#include "legalnotice.h"
#include "signalhandler.h"
#include "upgrade.h"
#ifndef DISABLE_GUI
#include "gui/utils.h"
@ -89,7 +89,6 @@ Q_IMPORT_PLUGIN(QICOPlugin)
using namespace std::chrono_literals;
void displayVersion();
bool userAgreesWithLegalNotice();
void displayBadArgMessage(const QString &message);
void displayErrorMessage(const QString &message);
@ -168,28 +167,6 @@ int main(int argc, char *argv[])
.arg(u"-h (or --help)"_s));
}
const bool firstTimeUser = !Preferences::instance()->getAcceptedLegal();
if (firstTimeUser)
{
#ifndef DISABLE_GUI
if (!userAgreesWithLegalNotice())
return EXIT_SUCCESS;
#elif defined(Q_OS_WIN)
if (_isatty(_fileno(stdin))
&& _isatty(_fileno(stdout))
&& !userAgreesWithLegalNotice())
return EXIT_SUCCESS;
#else
if (!params.shouldDaemonize
&& isatty(fileno(stdin))
&& isatty(fileno(stdout))
&& !userAgreesWithLegalNotice())
return EXIT_SUCCESS;
#endif
setCurrentMigrationVersion();
}
// Check if qBittorrent is already running
if (app->hasAnotherInstance())
{
@ -197,7 +174,14 @@ int main(int argc, char *argv[])
if (params.shouldDaemonize)
{
throw CommandLineParameterError(QCoreApplication::translate("Main", "You cannot use %1: qBittorrent is already running.")
.arg(u"-d (or --daemon)"_s));
.arg(u"-d (or --daemon)"_s));
}
// print friendly message if there are no other command line args
if (argc == 1)
{
const QString message = QCoreApplication::translate("Main", "Another qBittorrent instance is already running.");
printf("%s\n", qUtf8Printable(message));
}
#endif
@ -207,6 +191,26 @@ int main(int argc, char *argv[])
return EXIT_SUCCESS;
}
CachedSettingValue<bool> legalNoticeShown {u"LegalNotice/Accepted"_s, false};
if (params.confirmLegalNotice)
legalNoticeShown = true;
if (!legalNoticeShown)
{
#ifndef DISABLE_GUI
const bool isInteractive = true;
#elif defined(Q_OS_WIN)
const bool isInteractive = (_isatty(_fileno(stdin)) != 0) && (_isatty(_fileno(stdout)) != 0);
#else
// when run in daemon mode user can only dismiss the notice with command line option
const bool isInteractive = !params.shouldDaemonize
&& ((isatty(fileno(stdin)) != 0) && (isatty(fileno(stdout)) != 0));
#endif
showLegalNotice(isInteractive);
if (isInteractive)
legalNoticeShown = true;
}
#ifdef Q_OS_MACOS
// Since Apple made difficult for users to set PATH, we set here for convenience.
// Users are supposed to install Homebrew Python for search function.
@ -294,13 +298,13 @@ void displayBadArgMessage(const QString &message)
{
const QString help = QCoreApplication::translate("Main", "Run application with -h option to read about command line parameters.");
#if defined(Q_OS_WIN) && !defined(DISABLE_GUI)
QMessageBox msgBox(QMessageBox::Critical, QCoreApplication::translate("Main", "Bad command line"),
QMessageBox msgBox(QMessageBox::Critical, QCoreApplication::translate("Main", "Bad command line options"),
(message + u'\n' + help), QMessageBox::Ok);
msgBox.show(); // Need to be shown or to moveToCenter does not work
msgBox.move(Utils::Gui::screenCenter(&msgBox));
msgBox.exec();
#else
const QString errMsg = QCoreApplication::translate("Main", "Bad command line: ") + u'\n'
const QString errMsg = QCoreApplication::translate("Main", "Bad command line options:") + u'\n'
+ message + u'\n'
+ help + u'\n';
fprintf(stderr, "%s", qUtf8Printable(errMsg));
@ -331,45 +335,6 @@ void displayErrorMessage(const QString &message)
#endif
}
bool userAgreesWithLegalNotice()
{
Preferences *const pref = Preferences::instance();
Q_ASSERT(!pref->getAcceptedLegal());
#ifdef DISABLE_GUI
const QString eula = u"\n*** %1 ***\n"_s.arg(QCoreApplication::translate("Main", "Legal Notice"))
+ QCoreApplication::translate("Main", "qBittorrent is a file sharing program. When you run a torrent, its data will be made available to others by means of upload. Any content you share is your sole responsibility.") + u"\n\n"
+ QCoreApplication::translate("Main", "No further notices will be issued.") + u"\n\n"
+ QCoreApplication::translate("Main", "Press %1 key to accept and continue...").arg(u"'y'"_s) + u'\n';
printf("%s", qUtf8Printable(eula));
const char ret = getchar(); // Read pressed key
if ((ret == 'y') || (ret == 'Y'))
{
// Save the answer
pref->setAcceptedLegal(true);
return true;
}
#else
QMessageBox msgBox;
msgBox.setText(QCoreApplication::translate("Main", "qBittorrent is a file sharing program. When you run a torrent, its data will be made available to others by means of upload. Any content you share is your sole responsibility.\n\nNo further notices will be issued."));
msgBox.setWindowTitle(QCoreApplication::translate("Main", "Legal notice"));
msgBox.addButton(QCoreApplication::translate("Main", "Cancel"), QMessageBox::RejectRole);
const QAbstractButton *agreeButton = msgBox.addButton(QCoreApplication::translate("Main", "I Agree"), QMessageBox::AcceptRole);
msgBox.show(); // Need to be shown or to moveToCenter does not work
msgBox.move(Utils::Gui::screenCenter(&msgBox));
msgBox.exec();
if (msgBox.clickedButton() == agreeButton)
{
// Save the answer
pref->setAcceptedLegal(true);
return true;
}
#endif // DISABLE_GUI
return false;
}
#ifdef Q_OS_UNIX
void adjustFileDescriptorLimit()
{

View file

@ -1480,19 +1480,6 @@ void Preferences::setDNSLastIP(const QString &ip)
setValue(u"DNSUpdater/lastIP"_s, ip);
}
bool Preferences::getAcceptedLegal() const
{
return value(u"LegalNotice/Accepted"_s, false);
}
void Preferences::setAcceptedLegal(const bool accepted)
{
if (accepted == getAcceptedLegal())
return;
setValue(u"LegalNotice/Accepted"_s, accepted);
}
QByteArray Preferences::getMainGeometry() const
{
return value<QByteArray>(u"MainWindow/geometry"_s);

View file

@ -340,8 +340,6 @@ public:
void setDNSLastUpd(const QDateTime &date);
QString getDNSLastIP() const;
void setDNSLastIP(const QString &ip);
bool getAcceptedLegal() const;
void setAcceptedLegal(bool accepted);
QByteArray getMainGeometry() const;
void setMainGeometry(const QByteArray &geometry);
bool isFiltersSidebarVisible() const;

View file

@ -224,3 +224,9 @@ bool SettingsStorage::hasKey(const QString &key) const
const QReadLocker locker {&m_lock};
return m_data.contains(key);
}
bool SettingsStorage::isEmpty() const
{
const QReadLocker locker {&m_lock};
return m_data.isEmpty();
}

View file

@ -109,6 +109,7 @@ public:
void removeValue(const QString &key);
bool hasKey(const QString &key) const;
bool isEmpty() const;
public slots:
bool save();