implement terms of service check wizard page

this is only shown if the TOS haven't been accepted yet!

for now this only opens the browser, similar to the Flow2Auth page

the `TermsOfServiceCheckWidget` is a combination of the `Flow2Auth` and
the `Flow2AuthWidget` classes -- in the future we ideally display the
required TOS directly in the wizard

Signed-off-by: Jyrki Gadinger <nilsding@nilsding.org>
This commit is contained in:
Jyrki Gadinger 2025-02-17 18:01:08 +01:00 committed by Matthieu Gallien
parent 88400b1ef7
commit 34ace3ef27
No known key found for this signature in database
GPG Key ID: 7D0F74F05C22F553
13 changed files with 609 additions and 57 deletions

View File

@ -43,6 +43,7 @@ set(client_UI_SRCS
wizard/owncloudconnectionmethoddialog.ui
wizard/owncloudhttpcredspage.ui
wizard/owncloudsetupnocredspage.ui
wizard/termsofservicecheckwidget.ui
wizard/webview.ui
wizard/welcomepage.ui
)
@ -240,6 +241,8 @@ set(client_SRCS
wizard/flow2authwidget.cpp
wizard/owncloudsetuppage.h
wizard/owncloudsetuppage.cpp
wizard/termsofservicecheckwidget.h
wizard/termsofservicecheckwidget.cpp
wizard/termsofservicewizardpage.h
wizard/termsofservicewizardpage.cpp
wizard/owncloudwizardcommon.h

View File

@ -28,7 +28,6 @@
#include "sslerrordialog.h"
#include "wizard/owncloudwizard.h"
#include "wizard/owncloudwizardcommon.h"
#include "connectionvalidator.h"
#include "creds/credentialsfactory.h"
#include "creds/abstractcredentials.h"
@ -382,12 +381,20 @@ void OwncloudSetupWizard::testOwnCloudConnect()
job->setFollowRedirects(false);
job->setProperties(QList<QByteArray>() << "getlastmodified");
connect(job, &PropfindJob::result, _ocWizard, &OwncloudWizard::successfulStep);
connect(job, &PropfindJob::finishedWithError, this, [this] (QNetworkReply *reply) {
connect(job, &PropfindJob::finishedWithError, this, [this] (QNetworkReply *reply) -> void {
if (reply && reply->error() == QNetworkReply::ContentAccessDenied) {
testTermsOfService();
} else {
slotAuthError();
// A 403 might indicate that the terms of service need to be signed.
// catch this special case here, fall back to the standard error handler if it's not TOS-related
auto davException = OCC::getExceptionFromReply(reply);
if (!davException.first.isEmpty() && davException.first == QStringLiteral(R"(OCA\TermsOfService\TermsNotSignedException)")) {
// authentication was successful, but the user hasn't signed the terms of service yet. Prompt for that in the next step
qCInfo(lcWizard) << "Terms of service not accepted yet! Will prompt the user in the next step";
_ocWizard->_needsToAcceptTermsOfService = true;
_ocWizard->successfulStep();
return;
}
}
slotAuthError();
});
job->start();
@ -426,34 +433,25 @@ void OwncloudSetupWizard::slotAuthError()
"\"%1\". The URL is bad, the server is misconfigured.")
.arg(Utility::escape(redirectUrl.toString()));
} else if (reply->error() == QNetworkReply::ContentNotFoundError) {
// A 404 is actually a success: we were authorized to know that the folder does
// not exist. It will be created later...
} else if (reply->error() == QNetworkReply::ContentAccessDenied) {
testTermsOfService();
return;
} else if (reply->error() == QNetworkReply::ContentNotFoundError) {
_ocWizard->successfulStep();
return;
// Provide messages for other errors, such as invalid credentials.
} else if (reply->error() != QNetworkReply::NoError) {
auto davException = OCC::getExceptionFromReply(reply);
// Provide messages for other errors, such as invalid credentials.
if (!_ocWizard->account()->credentials()->stillValid(reply)) {
errorMsg = tr("Access forbidden by server. To verify that you have proper access, "
"<a href=\"%1\">click here</a> to access the service with your browser.")
.arg(Utility::escape(_ocWizard->account()->url().toString()));
} else if (!davException.first.isEmpty() && davException.first == QStringLiteral(R"(OCA\TermsOfService\TermsNotSignedException)")) {
qCInfo(lcWizard) << "Terms of service not accepted yet!";
// TODO: it would be cool to display a new wizard page containing the terms of service
errorMsg = tr("Please accept the <a href=\"%1\">Terms of Service</a> with your browser and try again.")
.arg(Utility::escape(_ocWizard->account()->url().toString()));
} else {
errorMsg = job->errorStringParsingBody();
}
// Something else went wrong, maybe the response was 200 but with invalid data.
} else {
// Something else went wrong, maybe the response was 200 but with invalid data.
errorMsg = tr("There was an invalid response to an authenticated WebDAV request");
}
@ -488,14 +486,6 @@ bool OwncloudSetupWizard::checkDowngradeAdvised(QNetworkReply *reply)
return true;
}
void OwncloudSetupWizard::testTermsOfService()
{
_termsOfServiceChecker = new TermsOfServiceChecker{_ocWizard->account(), this};
connect(_termsOfServiceChecker, &TermsOfServiceChecker::done, this, &OwncloudSetupWizard::termsOfServiceChecked);
_termsOfServiceChecker->start();
}
void OwncloudSetupWizard::slotCreateLocalAndRemoteFolders(const QString &localFolder, const QString &remoteFolder)
{
qCInfo(lcWizard) << "Setup local sync folder for new oC connection " << localFolder;
@ -749,17 +739,6 @@ void OwncloudSetupWizard::slotSkipFolderConfiguration()
emit ownCloudWizardDone(QDialog::Accepted);
}
void OwncloudSetupWizard::termsOfServiceChecked()
{
if (_termsOfServiceChecker && _termsOfServiceChecker->needToSign()) {
QDesktopServices::openUrl(_ocWizard->account()->url());
} else {
_ocWizard->successfulStep();
delete _termsOfServiceChecker;
_termsOfServiceChecker = nullptr;
}
}
AccountState *OwncloudSetupWizard::applyAccountChanges()
{
AccountPtr newAccount = _ocWizard->account();

View File

@ -45,6 +45,7 @@ public:
/** Run the wizard */
static void runWizard(QObject *obj, const char *amember, QWidget *parent = nullptr);
static bool bringWizardToFrontIfVisible();
signals:
// overall dialog close signal.
void ownCloudWizardDone(int);
@ -70,8 +71,6 @@ private slots:
void slotAssistantFinished(int);
void slotSkipFolderConfiguration();
void termsOfServiceChecked();
private:
explicit OwncloudSetupWizard(QObject *parent = nullptr);
~OwncloudSetupWizard() override;
@ -82,9 +81,7 @@ private:
bool ensureStartFromScratch(const QString &localFolder);
AccountState *applyAccountChanges();
bool checkDowngradeAdvised(QNetworkReply *reply);
void testTermsOfService();
TermsOfServiceChecker *_termsOfServiceChecker = nullptr;
OwncloudWizard *_ocWizard = nullptr;
QString _initLocalFolder;
QString _remoteFolder;

View File

@ -104,7 +104,13 @@ void Flow2AuthCredsPage::slotFlow2AuthResult(Flow2Auth::Result r, const QString
int Flow2AuthCredsPage::nextId() const
{
return WizardCommon::Page_TermsOfService;
const auto ocWizard = qobject_cast<OwncloudWizard *>(wizard());
Q_ASSERT(ocWizard);
if (ocWizard->needsToAcceptTermsOfService()) {
return WizardCommon::Page_TermsOfService;
}
return WizardCommon::Page_AdvancedSetup;
}
void Flow2AuthCredsPage::setConnected()

View File

@ -153,6 +153,12 @@ bool OwncloudHttpCredsPage::validatePage()
int OwncloudHttpCredsPage::nextId() const
{
const auto ocWizard = qobject_cast<OwncloudWizard *>(wizard());
Q_ASSERT(ocWizard);
if (ocWizard->needsToAcceptTermsOfService()) {
return WizardCommon::Page_TermsOfService;
}
return WizardCommon::Page_AdvancedSetup;
}

View File

@ -54,6 +54,7 @@ OwncloudWizard::OwncloudWizard(QWidget *parent)
, _setupPage(new OwncloudSetupPage(this))
, _httpCredsPage(new OwncloudHttpCredsPage(this))
, _flow2CredsPage(new Flow2AuthCredsPage)
, _termsOfServicePage(new TermsOfServiceWizardPage)
, _advancedSetupPage(new OwncloudAdvancedSetupPage(this))
#ifdef WITH_WEBENGINE
, _webViewPage(new WebViewPage(this))
@ -72,6 +73,7 @@ OwncloudWizard::OwncloudWizard(QWidget *parent)
setPage(WizardCommon::Page_ServerSetup, _setupPage);
setPage(WizardCommon::Page_HttpCreds, _httpCredsPage);
setPage(WizardCommon::Page_Flow2AuthCreds, _flow2CredsPage);
setPage(WizardCommon::Page_TermsOfService, _termsOfServicePage);
setPage(WizardCommon::Page_AdvancedSetup, _advancedSetupPage);
#ifdef WITH_WEBENGINE
if (!useFlow2()) {
@ -117,6 +119,7 @@ OwncloudWizard::OwncloudWizard(QWidget *parent)
connect(this, &OwncloudWizard::styleChanged, _setupPage, &OwncloudSetupPage::slotStyleChanged);
connect(this, &OwncloudWizard::styleChanged, _advancedSetupPage, &OwncloudAdvancedSetupPage::slotStyleChanged);
connect(this, &OwncloudWizard::styleChanged, _flow2CredsPage, &Flow2AuthCredsPage::slotStyleChanged);
connect(this, &OwncloudWizard::styleChanged, _termsOfServicePage, &TermsOfServiceWizardPage::styleChanged);
customizeStyle();
@ -217,6 +220,11 @@ bool OwncloudWizard::isConfirmBigFolderChecked() const
return _advancedSetupPage->isConfirmBigFolderChecked();
}
bool OwncloudWizard::needsToAcceptTermsOfService() const
{
return _needsToAcceptTermsOfService;
}
QString OwncloudWizard::ocUrl() const
{
QString url = field("OCUrl").toString().simplified();
@ -263,7 +271,7 @@ void OwncloudWizard::successfulStep()
#endif // WITH_WEBENGINE
case WizardCommon::Page_TermsOfService:
_termsOfServicePage->initializePage();
// nothing to do here
break;
case WizardCommon::Page_AdvancedSetup:
@ -292,6 +300,9 @@ void OwncloudWizard::slotCustomButtonClicked(const int which)
} else if (which == WizardButton::CustomButton2) {
// Because QWizard doesn't have a way of directly going to a specific page (!!!)
restart();
// in case the wizard had been cancelled at a page where the need for signing the TOS got checked:
_needsToAcceptTermsOfService = false;
}
}
@ -336,7 +347,8 @@ void OwncloudWizard::slotCurrentPageChanged(int id)
#ifdef WITH_WEBENGINE
id == WizardCommon::Page_WebView ||
#endif // WITH_WEBENGINE
id == WizardCommon::Page_Flow2AuthCreds) {
id == WizardCommon::Page_Flow2AuthCreds ||
id == WizardCommon::Page_TermsOfService) {
setButtonLayout({ QWizard::BackButton, QWizard::Stretch });
} else if (id == WizardCommon::Page_AdvancedSetup) {
setButtonLayout({ QWizard::CustomButton2, QWizard::Stretch, QWizard::CustomButton1, QWizard::FinishButton });

View File

@ -69,6 +69,7 @@ public:
[[nodiscard]] bool useFlow2() const;
[[nodiscard]] bool useVirtualFileSync() const;
[[nodiscard]] bool isConfirmBigFolderChecked() const;
[[nodiscard]] bool needsToAcceptTermsOfService() const;
void displayError(const QString &, bool retryHTTPonly);
[[nodiscard]] AbstractCredentials *getCredentials() const;
@ -140,6 +141,8 @@ private:
bool _useFlow2 = ConfigFile().forceLoginV2();
bool _needsToAcceptTermsOfService = false;
friend class OwncloudSetupWizard;
};

View File

@ -0,0 +1,194 @@
/*
* Copyright (C) by Jyrki Gadinger <nilsding@nilsding.org>
*
* 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.
*/
#include "termsofservicecheckwidget.h"
#include "wizard/owncloudwizardcommon.h"
#include "theme.h"
#include "configfile.h"
#include "QProgressIndicator.h"
#include <QClipboard>
#include <QDesktopServices>
namespace OCC {
Q_LOGGING_CATEGORY(lcTosCheckWidget, "nextcloud.gui.wizard.termsofservicecheckwidget", QtInfoMsg)
TermsOfServiceCheckWidget::TermsOfServiceCheckWidget(QWidget *parent)
: QWidget(parent)
, _progressIndicator(new QProgressIndicator(this))
{
_pollTimer.setInterval(1000);
QObject::connect(&_pollTimer, &QTimer::timeout, this, &TermsOfServiceCheckWidget::slotPollTimerTimeout);
_ui.setupUi(this);
connect(_ui.openLinkButton, &QPushButton::clicked, this, &TermsOfServiceCheckWidget::slotOpenBrowser);
connect(_ui.copyLinkButton, &QPushButton::clicked, this, &TermsOfServiceCheckWidget::slotCopyLinkToClipboard);
auto sizePolicy = _progressIndicator->sizePolicy();
sizePolicy.setRetainSizeWhenHidden(true);
_progressIndicator->setSizePolicy(sizePolicy);
_ui.progressLayout->addWidget(_progressIndicator);
stopSpinner(false);
customizeStyle();
}
TermsOfServiceCheckWidget::~TermsOfServiceCheckWidget() {
}
void TermsOfServiceCheckWidget::start()
{
ConfigFile cfg;
std::chrono::milliseconds polltime = cfg.remotePollInterval();
qCInfo(lcTosCheckWidget) << "setting remote poll timer interval to" << polltime.count() << "msec";
_secondsInterval = (polltime.count() / 1000);
_secondsLeft = _secondsInterval;
_pollTimer.start();
// open browser when the wizard page is shown
slotOpenBrowser();
}
void TermsOfServiceCheckWidget::setUrl(const QUrl &url)
{
_url = url;
}
void TermsOfServiceCheckWidget::termsNotAcceptedYet()
{
_secondsLeft = _secondsInterval;
_isBusy = false;
statusChanged(Status::statusPollCountdown);
}
void TermsOfServiceCheckWidget::setLogo()
{
const auto backgroundColor = palette().window().color();
const auto logoIconFileName = Theme::instance()->isBranded() ? Theme::hidpiFileName("external.png", backgroundColor)
: Theme::hidpiFileName(":/client/theme/colored/external.png");
_ui.logoLabel->setPixmap(logoIconFileName);
}
void TermsOfServiceCheckWidget::slotStyleChanged()
{
customizeStyle();
}
void TermsOfServiceCheckWidget::slotPollTimerTimeout()
{
if (_isBusy) {
return;
}
_isBusy = true;
_secondsLeft--;
if (_secondsLeft > 0) {
statusChanged(Status::statusPollCountdown);
_isBusy = false;
return;
}
statusChanged(Status::statusPollNow);
Q_EMIT pollNow();
}
void TermsOfServiceCheckWidget::slotOpenBrowser()
{
QDesktopServices::openUrl(_url);
}
void TermsOfServiceCheckWidget::slotCopyLinkToClipboard()
{
statusChanged(Status::statusCopyLinkToClipboard);
QApplication::clipboard()->setText(_url.toString(QUrl::FullyEncoded));
}
void TermsOfServiceCheckWidget::statusChanged(Status status)
{
switch (status)
{
case statusPollCountdown:
if (_statusUpdateSkipCount > 0) {
_statusUpdateSkipCount--;
return;
}
_ui.statusLabel->setText(tr("Waiting for terms to be accepted") + QStringLiteral("… (%1)").arg(_secondsLeft));
stopSpinner(true);
return;
case statusPollNow:
_statusUpdateSkipCount = 0;
_ui.statusLabel->setText(tr("Polling") + QStringLiteral(""));
startSpinner();
return;
case statusCopyLinkToClipboard:
_statusUpdateSkipCount = 3;
_ui.statusLabel->setText(tr("Link copied to clipboard."));
stopSpinner(true);
return;
}
}
void TermsOfServiceCheckWidget::startSpinner()
{
_ui.progressLayout->setEnabled(true);
_ui.statusLabel->setVisible(true);
_progressIndicator->setVisible(true);
_progressIndicator->startAnimation();
_ui.openLinkButton->setEnabled(false);
_ui.copyLinkButton->setEnabled(false);
}
void TermsOfServiceCheckWidget::stopSpinner(bool showStatusLabel)
{
_ui.progressLayout->setEnabled(false);
_ui.statusLabel->setVisible(showStatusLabel);
_progressIndicator->setVisible(false);
_progressIndicator->stopAnimation();
_ui.openLinkButton->setEnabled(_statusUpdateSkipCount == 0);
_ui.copyLinkButton->setEnabled(_statusUpdateSkipCount == 0);
}
void TermsOfServiceCheckWidget::customizeStyle()
{
setLogo();
if (_progressIndicator) {
const auto isDarkBackground = Theme::isDarkColor(palette().window().color());
if (isDarkBackground) {
_progressIndicator->setColor(Qt::white);
} else {
_progressIndicator->setColor(Qt::black);
}
}
_ui.openLinkButton->setText(tr("Open Browser"));
_ui.copyLinkButton->setText(tr("Copy Link"));
WizardCommon::customizeHintLabel(_ui.statusLabel);
}
} // namespace OCC

View File

@ -0,0 +1,72 @@
/*
* Copyright (C) by Jyrki Gadinger <nilsding@nilsding.org>
*
* 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.
*/
#pragma once
#include <QWidget>
#include <QTimer>
#include "ui_termsofservicecheckwidget.h"
class QProgressIndicator;
namespace OCC {
class TermsOfServiceCheckWidget : public QWidget
{
Q_OBJECT
public:
enum Status {
statusPollCountdown = 1,
statusPollNow,
statusCopyLinkToClipboard,
};
TermsOfServiceCheckWidget(QWidget *parent = nullptr);
~TermsOfServiceCheckWidget() override;
void start();
void setUrl(const QUrl &url);
void termsNotAcceptedYet();
public Q_SLOTS:
void slotStyleChanged();
Q_SIGNALS:
void pollNow();
private Q_SLOTS:
void slotPollTimerTimeout();
void slotOpenBrowser();
void slotCopyLinkToClipboard();
private:
Ui_TermsOfServiceCheckWidget _ui{};
QTimer _pollTimer;
QProgressIndicator *_progressIndicator = nullptr;
int _statusUpdateSkipCount = 0;
qint64 _secondsLeft = 0LL;
qint64 _secondsInterval = 0LL;
bool _isBusy = false;
QUrl _url;
void statusChanged(Status status);
void startSpinner();
void stopSpinner(bool showStatusLabel);
void customizeStyle();
void setLogo();
};
} // namespace OCC

View File

@ -0,0 +1,248 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>TermsOfServiceCheckWidget</class>
<widget class="QWidget" name="TermsOfServiceCheckWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>597</width>
<height>387</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="MinimumExpanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>500</width>
<height>280</height>
</size>
</property>
<property name="windowTitle">
<string>Terms of Service</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<spacer name="verticalSpacer_6">
<property name="orientation">
<enum>Qt::Orientation::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="logoLabel">
<property name="text">
<string>Logo</string>
</property>
<property name="alignment">
<set>Qt::AlignmentFlag::AlignCenter</set>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Orientation::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>32</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="label">
<property name="font">
<font>
<pointsize>12</pointsize>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Switch to your browser to accept the terms of service</string>
</property>
<property name="alignment">
<set>Qt::AlignmentFlag::AlignCenter</set>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer_4">
<property name="orientation">
<enum>Qt::Orientation::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Policy::Expanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>8</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="statusLabel">
<property name="text">
<string notr="true">Status</string>
</property>
<property name="alignment">
<set>Qt::AlignmentFlag::AlignCenter</set>
</property>
<property name="margin">
<number>0</number>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Orientation::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>32</height>
</size>
</property>
</spacer>
</item>
<item>
<layout class="QHBoxLayout" name="progressLayout"/>
</item>
<item>
<spacer name="verticalSpacer_5">
<property name="orientation">
<enum>Qt::Orientation::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>64</height>
</size>
</property>
</spacer>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Orientation::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QPushButton" name="copyLinkButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<pointsize>9</pointsize>
</font>
</property>
<property name="text">
<string notr="true">copyLinkButton</string>
</property>
<property name="autoDefault">
<bool>true</bool>
</property>
<property name="default">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="openLinkButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<pointsize>9</pointsize>
</font>
</property>
<property name="text">
<string notr="true">openLinkButton</string>
</property>
<property name="autoDefault">
<bool>true</bool>
</property>
<property name="default">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Orientation::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</item>
<item>
<spacer name="verticalSpacer_3">
<property name="orientation">
<enum>Qt::Orientation::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Policy::Expanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>60</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@ -18,6 +18,7 @@
#include "owncloudsetupwizard.h"
#include "wizard/owncloudwizard.h"
#include "wizard/owncloudwizardcommon.h"
#include "wizard/termsofservicecheckwidget.h"
#include "connectionvalidator.h"
#include <QVBoxLayout>
@ -29,14 +30,35 @@ OCC::TermsOfServiceWizardPage::TermsOfServiceWizardPage()
: QWizardPage()
{
_layout = new QVBoxLayout(this);
_termsOfServiceCheckWidget = new TermsOfServiceCheckWidget;
_layout->addWidget(_termsOfServiceCheckWidget);
connect(this, &TermsOfServiceWizardPage::styleChanged, _termsOfServiceCheckWidget, &TermsOfServiceCheckWidget::slotStyleChanged);
connect(_termsOfServiceCheckWidget, &TermsOfServiceCheckWidget::pollNow, this, &TermsOfServiceWizardPage::slotPollNow);
}
void OCC::TermsOfServiceWizardPage::initializePage()
{
_ocWizard = qobject_cast<OwncloudWizard *>(wizard());
Q_ASSERT(_ocWizard);
_termsOfServiceChecker = new TermsOfServiceChecker{_ocWizard->account(), this};
connect(_termsOfServiceChecker, &TermsOfServiceChecker::done, this, &TermsOfServiceWizardPage::termsOfServiceChecked);
_termsOfServiceCheckWidget->setUrl(_ocWizard->account()->url());
_termsOfServiceCheckWidget->slotStyleChanged();
_termsOfServiceCheckWidget->start();
connect(_ocWizard, &OwncloudWizard::onActivate, this, &TermsOfServiceWizardPage::slotPollNow);
}
void OCC::TermsOfServiceWizardPage::cleanupPage()
{
disconnect(_ocWizard, &OwncloudWizard::onActivate, this, &TermsOfServiceWizardPage::slotPollNow);
_termsOfServiceChecker->deleteLater();
_termsOfServiceChecker = nullptr;
}
int OCC::TermsOfServiceWizardPage::nextId() const
@ -51,21 +73,21 @@ bool OCC::TermsOfServiceWizardPage::isComplete() const
void TermsOfServiceWizardPage::slotPollNow()
{
_termsOfServiceChecker = new TermsOfServiceChecker{_ocWizard->account(), this};
if (!_termsOfServiceChecker) {
return;
}
connect(_termsOfServiceChecker, &TermsOfServiceChecker::done, this, &TermsOfServiceWizardPage::termsOfServiceChecked);
_termsOfServiceChecker->start();
}
void TermsOfServiceWizardPage::termsOfServiceChecked()
{
if (_termsOfServiceChecker && _termsOfServiceChecker->needToSign()) {
QDesktopServices::openUrl(_ocWizard->account()->url());
} else {
_ocWizard->successfulStep();
delete _termsOfServiceChecker;
_termsOfServiceChecker = nullptr;
_termsOfServiceCheckWidget->termsNotAcceptedYet();
return;
}
_ocWizard->successfulStep();
}
}

View File

@ -23,6 +23,7 @@ namespace OCC {
class OwncloudWizard;
class TermsOfServiceChecker;
class TermsOfServiceCheckWidget;
class TermsOfServiceWizardPage : public QWizardPage
{
@ -35,18 +36,21 @@ public:
[[nodiscard]] int nextId() const override;
[[nodiscard]] bool isComplete() const override;
Q_SIGNALS:
void connectToOCUrl(const QString &);
void pollNow();
private Q_SLOTS:
public Q_SLOTS:
void slotPollNow();
void termsOfServiceChecked();
Q_SIGNALS:
void pollNow();
void styleChanged();
private:
QVBoxLayout *_layout = nullptr;
OwncloudWizard *_ocWizard = nullptr;
TermsOfServiceChecker *_termsOfServiceChecker = nullptr;
TermsOfServiceCheckWidget *_termsOfServiceCheckWidget = nullptr;
private Q_SLOTS:
void termsOfServiceChecked();
};
} // namespace OCC

View File

@ -92,7 +92,13 @@ void WebViewPage::cleanupPage()
}
int WebViewPage::nextId() const {
return WizardCommon::Page_TermsOfService;
const auto ocWizard = qobject_cast<OwncloudWizard *>(wizard());
Q_ASSERT(ocWizard);
if (ocWizard->needsToAcceptTermsOfService()) {
return WizardCommon::Page_TermsOfService;
}
return WizardCommon::Page_AdvancedSetup;
}
bool WebViewPage::isComplete() const {