From 3fca9be768315b5e0000d8a3cb3be33c0ec7e481 Mon Sep 17 00:00:00 2001 From: Matthieu Gallien Date: Wed, 20 Aug 2025 18:42:28 +0200 Subject: [PATCH 1/7] feat(wizard): allow to set proxy settings when setting up a new account Signed-off-by: Matthieu Gallien --- src/gui/CMakeLists.txt | 3 + src/gui/wizard/owncloudsetupnocredspage.ui | 80 +++++-- src/gui/wizard/owncloudsetuppage.cpp | 9 + src/gui/wizard/owncloudsetuppage.h | 5 + src/gui/wizard/proxysettings.ui | 264 +++++++++++++++++++++ src/gui/wizard/proxysettings.ui.license | 2 + src/gui/wizard/wizardproxysettings.cpp | 13 + src/gui/wizard/wizardproxysettings.h | 21 ++ 8 files changed, 375 insertions(+), 22 deletions(-) create mode 100644 src/gui/wizard/proxysettings.ui create mode 100644 src/gui/wizard/proxysettings.ui.license create mode 100644 src/gui/wizard/wizardproxysettings.cpp create mode 100644 src/gui/wizard/wizardproxysettings.h diff --git a/src/gui/CMakeLists.txt b/src/gui/CMakeLists.txt index d389df77d7..a52e7d85fc 100644 --- a/src/gui/CMakeLists.txt +++ b/src/gui/CMakeLists.txt @@ -49,6 +49,7 @@ set(client_UI_SRCS wizard/termsofservicecheckwidget.ui wizard/webview.ui wizard/welcomepage.ui + wizard/proxysettings.ui ) qt_add_resources(client_UI_SRCS ../../resources.qrc ${CMAKE_SOURCE_DIR}/theme.qrc) @@ -254,6 +255,8 @@ set(client_SRCS wizard/welcomepage.cpp wizard/linklabel.h wizard/linklabel.cpp + wizard/wizardproxysettings.h + wizard/wizardproxysettings.cpp ) if (NOT DISABLE_ACCOUNT_MIGRATION) diff --git a/src/gui/wizard/owncloudsetupnocredspage.ui b/src/gui/wizard/owncloudsetupnocredspage.ui index d12a9e1438..5777cff4e0 100644 --- a/src/gui/wizard/owncloudsetupnocredspage.ui +++ b/src/gui/wizard/owncloudsetupnocredspage.ui @@ -36,10 +36,10 @@ - Qt::Vertical + Qt::Orientation::Vertical - QSizePolicy::Expanding + QSizePolicy::Policy::Expanding @@ -57,7 +57,7 @@ - Qt::Horizontal + Qt::Orientation::Horizontal @@ -77,7 +77,7 @@ - Qt::Horizontal + Qt::Orientation::Horizontal @@ -92,10 +92,10 @@ - Qt::Vertical + Qt::Orientation::Vertical - QSizePolicy::Minimum + QSizePolicy::Policy::Minimum @@ -129,7 +129,7 @@ 0 - QLayout::SetDefaultConstraint + QLayout::SizeConstraint::SetDefaultConstraint @@ -139,10 +139,10 @@ - Qt::Vertical + Qt::Orientation::Vertical - QSizePolicy::Minimum + QSizePolicy::Policy::Minimum @@ -160,7 +160,7 @@ - Qt::Horizontal + Qt::Orientation::Horizontal @@ -175,7 +175,6 @@ 12 - 75 true @@ -187,7 +186,7 @@ - Qt::Horizontal + Qt::Orientation::Horizontal @@ -210,10 +209,10 @@ - Qt::Horizontal + Qt::Orientation::Horizontal - QSizePolicy::Expanding + QSizePolicy::Policy::Expanding @@ -262,7 +261,7 @@ This is the link to your %1 web interface when you open it in the browser. - Qt::AlignCenter + Qt::AlignmentFlag::AlignCenter true @@ -274,10 +273,10 @@ - Qt::Horizontal + Qt::Orientation::Horizontal - QSizePolicy::Expanding + QSizePolicy::Policy::Expanding @@ -301,7 +300,7 @@ Error Label - Qt::RichText + Qt::TextFormat::RichText true @@ -311,13 +310,50 @@ + + + + + + Qt::Orientation::Horizontal + + + + 40 + 20 + + + + + + + + Proxy Settings + + + + + + + Qt::Orientation::Horizontal + + + + 40 + 20 + + + + + + - Qt::Vertical + Qt::Orientation::Vertical - QSizePolicy::MinimumExpanding + QSizePolicy::Policy::MinimumExpanding @@ -337,10 +373,10 @@ - Qt::Vertical + Qt::Orientation::Vertical - QSizePolicy::MinimumExpanding + QSizePolicy::Policy::MinimumExpanding diff --git a/src/gui/wizard/owncloudsetuppage.cpp b/src/gui/wizard/owncloudsetuppage.cpp index 156deaf0f3..2e64d59f69 100644 --- a/src/gui/wizard/owncloudsetuppage.cpp +++ b/src/gui/wizard/owncloudsetuppage.cpp @@ -80,6 +80,9 @@ OwncloudSetupPage::OwncloudSetupPage(QWidget *parent) addCertDial = new AddCertificateDialog(this); connect(addCertDial, &QDialog::accepted, this, &OwncloudSetupPage::slotCertificateAccepted); + + connect(_ui.proxySettingsButton, &QPushButton::clicked, + this, &OwncloudSetupPage::slotSetProxySettings); } void OwncloudSetupPage::setLogo() @@ -170,6 +173,12 @@ void OwncloudSetupPage::slotUrlEditFinished() } } +void OwncloudSetupPage::slotSetProxySettings() +{ + _proxySettingsDialog = new WizardProxySettings{this}; + _proxySettingsDialog->show(); +} + bool OwncloudSetupPage::isComplete() const { return (!_ui.leUrl->text().isEmpty() || !_ui.comboBox->currentData().toString().isEmpty()) && !_checking; diff --git a/src/gui/wizard/owncloudsetuppage.h b/src/gui/wizard/owncloudsetuppage.h index cd898c901b..fc72d6a792 100644 --- a/src/gui/wizard/owncloudsetuppage.h +++ b/src/gui/wizard/owncloudsetuppage.h @@ -14,6 +14,7 @@ #include "../addcertificatedialog.h" #include "wizard/owncloudconnectionmethoddialog.h" +#include "wizard/wizardproxysettings.h" #include "ui_owncloudsetupnocredspage.h" @@ -59,6 +60,8 @@ protected slots: void slotUrlChanged(const QString &); void slotUrlEditFinished(); + void slotSetProxySettings(); + void setupCustomization(); signals: @@ -81,6 +84,8 @@ private: OwncloudWizard *_ocWizard; AddCertificateDialog *addCertDial = nullptr; + WizardProxySettings *_proxySettingsDialog = nullptr; + // Grab the forceLoginV2-setting from the wizard bool useFlow2 = _ocWizard->useFlow2(); }; diff --git a/src/gui/wizard/proxysettings.ui b/src/gui/wizard/proxysettings.ui new file mode 100644 index 0000000000..ffee2ef215 --- /dev/null +++ b/src/gui/wizard/proxysettings.ui @@ -0,0 +1,264 @@ + + + ProxySettings + + + + 0 + 0 + 481 + 296 + + + + Form + + + + + + true + + + + 0 + 0 + + + + Proxy Settings + + + + + + No proxy + + + true + + + + + + + Qt::Orientation::Horizontal + + + + 40 + 20 + + + + + + + + Use system proxy + + + + + + + + + true + + + + 0 + 0 + + + + + 0 + + + + + + + true + + + + 0 + 0 + + + + + + + + Qt::Orientation::Horizontal + + + + 40 + 20 + + + + + + + + + + + + Host + + + + + + + + 1 + 0 + + + + + + + + + + + : + + + + + + + + 0 + 0 + + + + 1 + + + 65535 + + + 8080 + + + + + + + + + false + + + Proxy server requires authentication + + + + + + + true + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + false + + + + 1 + 0 + + + + + + + + + + + false + + + + 1 + 0 + + + + + + + QLineEdit::EchoMode::Password + + + + + + + + + + Note: proxy settings have no effects for accounts on localhost + + + + + + + + + + Qt::Orientation::Horizontal + + + + 40 + 20 + + + + + + + + + + Manually specify proxy + + + + + + + + + + + diff --git a/src/gui/wizard/proxysettings.ui.license b/src/gui/wizard/proxysettings.ui.license new file mode 100644 index 0000000000..7be3270ab4 --- /dev/null +++ b/src/gui/wizard/proxysettings.ui.license @@ -0,0 +1,2 @@ +SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors +SPDX-License-Identifier: GPL-2.0-or-later diff --git a/src/gui/wizard/wizardproxysettings.cpp b/src/gui/wizard/wizardproxysettings.cpp new file mode 100644 index 0000000000..8d61d3028f --- /dev/null +++ b/src/gui/wizard/wizardproxysettings.cpp @@ -0,0 +1,13 @@ +/* + * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "wizardproxysettings.h" + +WizardProxySettings::WizardProxySettings(QWidget *parent) + : QDialog(parent) +{ + _ui.setupUi(this); + setWindowModality(Qt::WindowModal); +} diff --git a/src/gui/wizard/wizardproxysettings.h b/src/gui/wizard/wizardproxysettings.h new file mode 100644 index 0000000000..2cb93998dd --- /dev/null +++ b/src/gui/wizard/wizardproxysettings.h @@ -0,0 +1,21 @@ +/* + * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#pragma once + +#include + +#include "ui_proxysettings.h" + +class WizardProxySettings : public QDialog +{ + Q_OBJECT +public: + explicit WizardProxySettings(QWidget *parent = nullptr); + +private: + Ui_ProxySettings _ui{}; + +}; From 5373060cd036de713d93958bf83a7f3d8a8e66a0 Mon Sep 17 00:00:00 2001 From: Matthieu Gallien Date: Thu, 21 Aug 2025 14:00:44 +0200 Subject: [PATCH 2/7] feat(wizard): makes entering proxy settings feasible for new accounts Signed-off-by: Matthieu Gallien --- src/gui/wizard/owncloudsetuppage.cpp | 4 +- src/gui/wizard/proxysettings.ui | 100 ++++++++++------- src/gui/wizard/wizardproxysettings.cpp | 147 ++++++++++++++++++++++++- src/gui/wizard/wizardproxysettings.h | 42 ++++++- 4 files changed, 250 insertions(+), 43 deletions(-) diff --git a/src/gui/wizard/owncloudsetuppage.cpp b/src/gui/wizard/owncloudsetuppage.cpp index 2e64d59f69..3016ade5d9 100644 --- a/src/gui/wizard/owncloudsetuppage.cpp +++ b/src/gui/wizard/owncloudsetuppage.cpp @@ -161,6 +161,7 @@ void OwncloudSetupPage::slotUrlChanged(const QString &url) if (newUrl != url) { _ui.leUrl->setText(newUrl); } + _ui.proxySettingsButton->setEnabled(!_ui.leUrl->fullText().isEmpty()); } void OwncloudSetupPage::slotUrlEditFinished() @@ -175,7 +176,7 @@ void OwncloudSetupPage::slotUrlEditFinished() void OwncloudSetupPage::slotSetProxySettings() { - _proxySettingsDialog = new WizardProxySettings{this}; + _proxySettingsDialog = new WizardProxySettings{QUrl::fromUserInput(_ui.leUrl->fullText()), this}; _proxySettingsDialog->show(); } @@ -200,6 +201,7 @@ void OwncloudSetupPage::initializePage() } _ui.leUrl->setFocus(); + _ui.proxySettingsButton->setEnabled(false); const auto isServerUrlOverridden = !Theme::instance()->overrideServerUrl().isEmpty(); if (isServerUrlOverridden && !Theme::instance()->forceOverrideServerUrl()) { diff --git a/src/gui/wizard/proxysettings.ui b/src/gui/wizard/proxysettings.ui index ffee2ef215..292e4451f7 100644 --- a/src/gui/wizard/proxysettings.ui +++ b/src/gui/wizard/proxysettings.ui @@ -29,40 +29,17 @@ Proxy Settings - - + + - No proxy - - - true - - - - - - - Qt::Orientation::Horizontal - - - - 40 - 20 - - - - - - - - Use system proxy + Manually specify proxy - + true @@ -79,7 +56,7 @@ - + true @@ -109,14 +86,14 @@ - + Host - + 1 @@ -129,14 +106,14 @@ - + : - + 0 @@ -157,7 +134,7 @@ - + false @@ -167,7 +144,7 @@ - + true @@ -185,7 +162,7 @@ 0 - + false @@ -201,7 +178,7 @@ - + false @@ -223,7 +200,7 @@ - + Note: proxy settings have no effects for accounts on localhost @@ -247,16 +224,59 @@ - - + + - Manually specify proxy + Use system proxy + + + + No proxy + + + true + + + + + + + Qt::Orientation::Horizontal + + + + 40 + 20 + + + + + + + + Qt::Orientation::Vertical + + + + 20 + 40 + + + + + + + + QDialogButtonBox::StandardButton::Cancel|QDialogButtonBox::StandardButton::Ok + + + diff --git a/src/gui/wizard/wizardproxysettings.cpp b/src/gui/wizard/wizardproxysettings.cpp index 8d61d3028f..9f296aff01 100644 --- a/src/gui/wizard/wizardproxysettings.cpp +++ b/src/gui/wizard/wizardproxysettings.cpp @@ -5,9 +5,154 @@ #include "wizardproxysettings.h" -WizardProxySettings::WizardProxySettings(QWidget *parent) +#include +#include + +namespace OCC { + +Q_LOGGING_CATEGORY(lcWizardProxySettings, "nextcloud.gui.wizard.proxysettings", QtInfoMsg) + +WizardProxySettings::WizardProxySettings(QUrl serverURL, QWidget *parent) : QDialog(parent) + , _serverURL(std::move(serverURL)) { _ui.setupUi(this); + setWindowModality(Qt::WindowModal); + setWindowTitle(tr("Proxy Settigs", "Dialog window title for proxy settings")); + + _ui.hostLineEdit->setPlaceholderText(tr("Hostname of proxy server")); + _ui.userLineEdit->setPlaceholderText(tr("Username for proxy server")); + _ui.passwordLineEdit->setPlaceholderText(tr("Password for proxy server")); + + _ui.typeComboBox->addItem(tr("HTTP(S) proxy"), QNetworkProxy::HttpProxy); + _ui.typeComboBox->addItem(tr("SOCKS5 proxy"), QNetworkProxy::Socks5Proxy); + + _ui.authRequiredcheckBox->setEnabled(true); + + // Explicitly set up the enabled status of the proxy auth widgets to ensure + // toggling the parent enables/disables the children + _ui.userLineEdit->setEnabled(true); + _ui.passwordLineEdit->setEnabled(true); + _ui.authWidgets->setEnabled(_ui.authRequiredcheckBox->isChecked()); + connect(_ui.authRequiredcheckBox, &QAbstractButton::toggled, _ui.authWidgets, &QWidget::setEnabled); + + connect(_ui.manualProxyRadioButton, &QAbstractButton::toggled, _ui.manualSettings, &QWidget::setVisible); + connect(_ui.manualProxyRadioButton, &QAbstractButton::toggled, this, &WizardProxySettings::validateProxySettings); + + connect(_ui.typeComboBox, static_cast(&QComboBox::currentIndexChanged), this, &WizardProxySettings::validateProxySettings); + connect(_ui.hostLineEdit, &QLineEdit::editingFinished, this, &WizardProxySettings::validateProxySettings); + connect(_ui.userLineEdit, &QLineEdit::editingFinished, this, &WizardProxySettings::validateProxySettings); + connect(_ui.passwordLineEdit, &QLineEdit::editingFinished, this, &WizardProxySettings::validateProxySettings); + connect(_ui.portSpinBox, &QAbstractSpinBox::editingFinished, this, &WizardProxySettings::validateProxySettings); + connect(_ui.authRequiredcheckBox, &QAbstractButton::toggled, this, &WizardProxySettings::validateProxySettings); + + // Warn about empty proxy host + connect(_ui.hostLineEdit, &QLineEdit::textChanged, this, &WizardProxySettings::checkEmptyProxyHost); + connect(_ui.hostLineEdit, &QLineEdit::textChanged, this, &WizardProxySettings::validateProxySettings); + + connect(_ui.userLineEdit, &QLineEdit::textChanged, this, &WizardProxySettings::checkEmptyProxyCredentials); + connect(_ui.passwordLineEdit, &QLineEdit::textChanged, this, &WizardProxySettings::checkEmptyProxyCredentials); + connect(_ui.authRequiredcheckBox, &QAbstractButton::toggled, this, &WizardProxySettings::checkEmptyProxyCredentials); + + connect(_ui.buttonBox, &QDialogButtonBox::accepted, + this, &WizardProxySettings::settingsDone); + connect(_ui.buttonBox, &QDialogButtonBox::rejected, + this, &WizardProxySettings::reject); + + checkEmptyProxyHost(); + checkAccountLocalhost(); + + _ui.noProxyRadioButton->setChecked(true); + _ui.noProxyRadioButton->setFocus(); + _ui.manualSettings->setVisible(false); +} + +void WizardProxySettings::checkEmptyProxyHost() +{ + if (_ui.hostLineEdit->isEnabled() && _ui.hostLineEdit->text().isEmpty()) { + _ui.hostLineEdit->setStyleSheet("border: 1px solid red"); + } else { + _ui.hostLineEdit->setStyleSheet(QString()); + } +} + +void WizardProxySettings::checkEmptyProxyCredentials() +{ + if (!_ui.authRequiredcheckBox->isChecked()) { + _ui.userLineEdit->setStyleSheet(QString()); + _ui.passwordLineEdit->setStyleSheet(QString()); + return; + } + + if (_ui.userLineEdit->text().isEmpty()) { + _ui.userLineEdit->setStyleSheet("border: 1px solid red"); + } else { + _ui.userLineEdit->setStyleSheet(QString()); + } + + if (_ui.passwordLineEdit->text().isEmpty()) { + _ui.passwordLineEdit->setStyleSheet("border: 1px solid red"); + } else { + _ui.passwordLineEdit->setStyleSheet(QString()); + } +} + +void WizardProxySettings::checkAccountLocalhost() +{ + auto visible = false; + if (_ui.manualProxyRadioButton->isChecked()) { + const auto host = _serverURL.host(); + // Some typical url for localhost + if (host == "localhost" || host.startsWith("127.") || host == "[::1]") { + visible = true; + } + } + _ui.labelLocalhost->setVisible(visible); +} + +void WizardProxySettings::validateProxySettings() +{ + checkEmptyProxyHost(); + + _user = _ui.userLineEdit->text(); + _password = _ui.passwordLineEdit->text(); + _host = _ui.hostLineEdit->text(); + _port = _ui.portSpinBox->value(); + _needsAuth = _ui.authRequiredcheckBox->isChecked() ? ProxyAuthentication::AuthenticationRequired : ProxyAuthentication::NoAuthentication; + + _proxyType = QNetworkProxy::NoProxy; + _valid = false; + + if (_ui.noProxyRadioButton->isChecked()) { + _proxyType = QNetworkProxy::NoProxy; + _valid = true; + } else if (_ui.systemProxyRadioButton->isChecked()) { + _proxyType = QNetworkProxy::DefaultProxy; + _valid = true; + } else if (_ui.manualProxyRadioButton->isChecked()) { + _proxyType = _ui.typeComboBox->itemData(_ui.typeComboBox->currentIndex()).value(); + _valid = true; + if (_host.isEmpty()) { + _proxyType = QNetworkProxy::NoProxy; + _valid = false; + } + if (_ui.authRequiredcheckBox->isChecked() && (_user.isEmpty() || _password.isEmpty())) { + _proxyType = QNetworkProxy::NoProxy; + _valid = false; + } + } + + const auto okButton = _ui.buttonBox->button(QDialogButtonBox::Ok); + if (okButton) { + okButton->setEnabled(_valid); + } +} + +void WizardProxySettings::settingsDone() +{ + Q_EMIT proxySettingsAccepted(_user, _password, _host, _port, _needsAuth, _proxyType); + accept(); +} + } diff --git a/src/gui/wizard/wizardproxysettings.h b/src/gui/wizard/wizardproxysettings.h index 2cb93998dd..9305d8f725 100644 --- a/src/gui/wizard/wizardproxysettings.h +++ b/src/gui/wizard/wizardproxysettings.h @@ -6,16 +6,56 @@ #pragma once #include +#include #include "ui_proxysettings.h" +namespace OCC { + class WizardProxySettings : public QDialog { Q_OBJECT public: - explicit WizardProxySettings(QWidget *parent = nullptr); + enum class ProxyAuthentication { + AuthenticationRequired, + NoAuthentication, + }; + + explicit WizardProxySettings(QUrl serverURL, QWidget *parent = nullptr); + +Q_SIGNALS: + void proxySettingsAccepted(QString user, + QString password, + QString host, + int port, + WizardProxySettings::ProxyAuthentication needsAuth, + QNetworkProxy::ProxyType proxyType); + +private Q_SLOTS: + /// Red marking of host field if empty and enabled + void checkEmptyProxyHost(); + + void checkEmptyProxyCredentials(); + + void checkAccountLocalhost(); + + void validateProxySettings(); + + void settingsDone(); private: Ui_ProxySettings _ui{}; + QUrl _serverURL; + + bool _valid = false; + + QString _user; + QString _password; + QString _host; + int _port; + ProxyAuthentication _needsAuth = ProxyAuthentication::NoAuthentication; + QNetworkProxy::ProxyType _proxyType = QNetworkProxy::NoProxy; }; + +} From 7f599dc917e0f7da26494e970d8bddaa555ee78c Mon Sep 17 00:00:00 2001 From: Matthieu Gallien Date: Fri, 22 Aug 2025 11:42:02 +0200 Subject: [PATCH 3/7] feat(wizard): improve design of new account wizard improved Next and Back button texts less intrusive proxy settings button Signed-off-by: Matthieu Gallien --- src/gui/wizard/owncloudsetupnocredspage.ui | 37 ------------------- src/gui/wizard/owncloudsetuppage.cpp | 43 ++++++++++++++++++++-- src/gui/wizard/owncloudsetuppage.h | 4 ++ src/gui/wizard/owncloudwizard.cpp | 23 +++++++++--- src/gui/wizard/owncloudwizard.h | 2 + 5 files changed, 63 insertions(+), 46 deletions(-) diff --git a/src/gui/wizard/owncloudsetupnocredspage.ui b/src/gui/wizard/owncloudsetupnocredspage.ui index 5777cff4e0..62391b1689 100644 --- a/src/gui/wizard/owncloudsetupnocredspage.ui +++ b/src/gui/wizard/owncloudsetupnocredspage.ui @@ -310,43 +310,6 @@ - - - - - - Qt::Orientation::Horizontal - - - - 40 - 20 - - - - - - - - Proxy Settings - - - - - - - Qt::Orientation::Horizontal - - - - 40 - 20 - - - - - - diff --git a/src/gui/wizard/owncloudsetuppage.cpp b/src/gui/wizard/owncloudsetuppage.cpp index 3016ade5d9..e8a7b76abe 100644 --- a/src/gui/wizard/owncloudsetuppage.cpp +++ b/src/gui/wizard/owncloudsetuppage.cpp @@ -18,6 +18,7 @@ #include #include #include +#include #include "QProgressIndicator.h" @@ -81,8 +82,6 @@ OwncloudSetupPage::OwncloudSetupPage(QWidget *parent) addCertDial = new AddCertificateDialog(this); connect(addCertDial, &QDialog::accepted, this, &OwncloudSetupPage::slotCertificateAccepted); - connect(_ui.proxySettingsButton, &QPushButton::clicked, - this, &OwncloudSetupPage::slotSetProxySettings); } void OwncloudSetupPage::setLogo() @@ -96,6 +95,21 @@ void OwncloudSetupPage::setupServerAddressDescriptionLabel() _ui.serverAddressDescriptionLabel->setText(tr("The link to your %1 web interface when you open it in the browser.", "%1 will be replaced with the application name").arg(appName)); } +void OwncloudSetupPage::setProxySettingsButtonEnabled(bool enable) +{ + if (!wizard()) { + return; + } + + const auto proxySettingsButton = wizard()->button(QWizard::CustomButton3); + + if (!proxySettingsButton) { + return; + } + + proxySettingsButton->setEnabled(enable); +} + void OwncloudSetupPage::setServerUrl(const QString &newUrl) { _ocWizard->setRegistration(false); @@ -161,7 +175,7 @@ void OwncloudSetupPage::slotUrlChanged(const QString &url) if (newUrl != url) { _ui.leUrl->setText(newUrl); } - _ui.proxySettingsButton->setEnabled(!_ui.leUrl->fullText().isEmpty()); + setProxySettingsButtonEnabled(!_ui.leUrl->fullText().isEmpty()); } void OwncloudSetupPage::slotUrlEditFinished() @@ -201,7 +215,8 @@ void OwncloudSetupPage::initializePage() } _ui.leUrl->setFocus(); - _ui.proxySettingsButton->setEnabled(false); + + setProxySettingsButtonEnabled(false); const auto isServerUrlOverridden = !Theme::instance()->overrideServerUrl().isEmpty(); if (isServerUrlOverridden && !Theme::instance()->forceOverrideServerUrl()) { @@ -220,6 +235,26 @@ void OwncloudSetupPage::initializePage() validatePage(); setVisible(false); } + + ensureProxySettingsButtonIsConnected(); +} + +void OwncloudSetupPage::ensureProxySettingsButtonIsConnected() +{ + if (!wizard()) { + return; + } + + const auto proxySettingsButton = wizard()->button(QWizard::CustomButton3); + + if (!proxySettingsButton) { + return; + } + + disconnect(_proxyButtonIsConnected); + + _proxyButtonIsConnected = connect(proxySettingsButton, &QPushButton::clicked, + this, &OwncloudSetupPage::slotSetProxySettings); } int OwncloudSetupPage::nextId() const diff --git a/src/gui/wizard/owncloudsetuppage.h b/src/gui/wizard/owncloudsetuppage.h index fc72d6a792..4edd1dd764 100644 --- a/src/gui/wizard/owncloudsetuppage.h +++ b/src/gui/wizard/owncloudsetuppage.h @@ -72,6 +72,9 @@ private: void customizeStyle(); void setupServerAddressDescriptionLabel(); + void setProxySettingsButtonEnabled(bool enable); + void ensureProxySettingsButtonIsConnected(); + Ui_OwncloudSetupPage _ui{}; QString _oCUrl; @@ -85,6 +88,7 @@ private: AddCertificateDialog *addCertDial = nullptr; WizardProxySettings *_proxySettingsDialog = nullptr; + QMetaObject::Connection _proxyButtonIsConnected; // Grab the forceLoginV2-setting from the wizard bool useFlow2 = _ocWizard->useFlow2(); diff --git a/src/gui/wizard/owncloudwizard.cpp b/src/gui/wizard/owncloudwizard.cpp index 536fb37be1..a7243659fc 100644 --- a/src/gui/wizard/owncloudwizard.cpp +++ b/src/gui/wizard/owncloudwizard.cpp @@ -98,6 +98,10 @@ OwncloudWizard::OwncloudWizard(QWidget *parent) setOption(QWizard::NoCancelButton); setButtonText(QWizard::CustomButton1, tr("Skip folders configuration")); setButtonText(QWizard::CustomButton2, tr("Cancel")); + setButtonText(QWizard::CustomButton3, tr("Proxy Settings", "Proxy Settings button text in new account wizard")); + + setButtonText(QWizard::NextButton, tr("Next", "Next button text in new account wizard")); + setButtonText(QWizard::BackButton, tr("Back", "Next button text in new account wizard")); // Change the next buttons size policy since we hide it on the // welcome page but want it to fill it's space that we don't get @@ -163,6 +167,12 @@ QList OwncloudWizard::calculateWizardPageSizes() const return pageSizes; } +void OwncloudWizard::ensureWelcomePageCorrectLayout() +{ + setButtonLayout({QWizard::NextButton}); + button(QWizard::NextButton)->setHidden(true); +} + QSize OwncloudWizard::calculateLargestSizeOfWizardPages(const QList &pageSizes) const { QSize largestSize; @@ -330,8 +340,8 @@ void OwncloudWizard::slotCurrentPageChanged(int id) }; if (id == WizardCommon::Page_Welcome) { - // Set next button to just hidden so it retains it's layout - button(QWizard::NextButton)->setHidden(true); + ensureWelcomePageCorrectLayout(); + // Need to set it from here, otherwise it has no effect _welcomePage->setLoginButtonDefault(); } else if ( @@ -340,12 +350,15 @@ void OwncloudWizard::slotCurrentPageChanged(int id) #endif // WITH_WEBENGINE id == WizardCommon::Page_Flow2AuthCreds || id == WizardCommon::Page_TermsOfService) { - setButtonLayout({ QWizard::BackButton, QWizard::Stretch }); + setButtonLayout({QWizard::BackButton, QWizard::Stretch}); } else if (id == WizardCommon::Page_AdvancedSetup) { - setButtonLayout({ QWizard::CustomButton2, QWizard::Stretch, QWizard::CustomButton1, QWizard::FinishButton }); + setButtonLayout({QWizard::CustomButton2, QWizard::Stretch, QWizard::CustomButton1, QWizard::FinishButton}); + setNextButtonAsDefault(); + } else if (id == WizardCommon::Page_ServerSetup) { + setButtonLayout({QWizard::BackButton, QWizard::Stretch, QWizard::CustomButton3, QWizard::NextButton}); setNextButtonAsDefault(); } else { - setButtonLayout({ QWizard::BackButton, QWizard::Stretch, QWizard::NextButton }); + setButtonLayout({QWizard::BackButton, QWizard::Stretch, QWizard::NextButton}); setNextButtonAsDefault(); } diff --git a/src/gui/wizard/owncloudwizard.h b/src/gui/wizard/owncloudwizard.h index 5737e7d5af..76e41ede3a 100644 --- a/src/gui/wizard/owncloudwizard.h +++ b/src/gui/wizard/owncloudwizard.h @@ -115,6 +115,8 @@ private: [[nodiscard]] QSize calculateLargestSizeOfWizardPages(const QList &pageSizes) const; [[nodiscard]] QList calculateWizardPageSizes() const; + void ensureWelcomePageCorrectLayout(); + AccountPtr _account; WelcomePage *_welcomePage = nullptr; OwncloudSetupPage *_setupPage = nullptr; From c8002bb94e0c80bbbcd8707637d834e514bb725b Mon Sep 17 00:00:00 2001 From: Matthieu Gallien Date: Mon, 25 Aug 2025 10:30:15 +0200 Subject: [PATCH 4/7] feat(proxy): store and modify proxy settings for use with new account connect the new UI to real proxy settings and allow modification and store them when the user has finished setting them up close #8602 Signed-off-by: Matthieu Gallien --- src/gui/CMakeLists.txt | 4 +- src/gui/owncloudsetupwizard.cpp | 36 ++++-- src/gui/owncloudsetupwizard.h | 4 +- src/gui/wizard/owncloudsetuppage.cpp | 19 +-- src/gui/wizard/owncloudsetuppage.h | 11 +- src/gui/wizard/owncloudwizard.h | 3 +- ...ings.cpp => wizardproxysettingsdialog.cpp} | 112 ++++++++++++------ ...settings.h => wizardproxysettingsdialog.h} | 30 ++--- 8 files changed, 136 insertions(+), 83 deletions(-) rename src/gui/wizard/{wizardproxysettings.cpp => wizardproxysettingsdialog.cpp} (53%) rename src/gui/wizard/{wizardproxysettings.h => wizardproxysettingsdialog.h} (51%) diff --git a/src/gui/CMakeLists.txt b/src/gui/CMakeLists.txt index a52e7d85fc..a9491e5be5 100644 --- a/src/gui/CMakeLists.txt +++ b/src/gui/CMakeLists.txt @@ -255,8 +255,8 @@ set(client_SRCS wizard/welcomepage.cpp wizard/linklabel.h wizard/linklabel.cpp - wizard/wizardproxysettings.h - wizard/wizardproxysettings.cpp + wizard/wizardproxysettingsdialog.h + wizard/wizardproxysettingsdialog.cpp ) if (NOT DISABLE_ACCOUNT_MIGRATION) diff --git a/src/gui/owncloudsetupwizard.cpp b/src/gui/owncloudsetupwizard.cpp index ba7ded88ec..0116b23901 100644 --- a/src/gui/owncloudsetupwizard.cpp +++ b/src/gui/owncloudsetupwizard.cpp @@ -146,20 +146,34 @@ void OwncloudSetupWizard::startWizard() } // also checks if an installation is valid and determines auth type in a second step -void OwncloudSetupWizard::slotCheckServer(const QString &urlString) +void OwncloudSetupWizard::slotCheckServer(const QUrl &serverURL, const OCC::WizardProxySettingsDialog::WizardProxySettings &proxySettings) { - QString fixedUrl = urlString; - QUrl url = QUrl::fromUserInput(fixedUrl); - // fromUserInput defaults to http, not http if no scheme is specified - if (!fixedUrl.startsWith("http://") && !fixedUrl.startsWith("https://")) { - url.setScheme("https"); - } AccountPtr account = _ocWizard->account(); - account->setUrl(url); + account->setUrl(serverURL); - // Reset the proxy which might had been determined previously in ConnectionValidator::checkServerAndAuth() - // when there was a previous account. - account->networkAccessManager()->setProxy(QNetworkProxy(QNetworkProxy::NoProxy)); + account->setProxyType(proxySettings._proxyType); + switch (proxySettings._proxyType) + { + case QNetworkProxy::HttpCachingProxy: + case QNetworkProxy::FtpCachingProxy: + case QNetworkProxy::NoProxy: + case QNetworkProxy::ProxyType::DefaultProxy: + // Reset the proxy which might had been determined previously in ConnectionValidator::checkServerAndAuth() + // when there was a previous account. + account->networkAccessManager()->setProxy({QNetworkProxy::NoProxy}); + break; + case QNetworkProxy::Socks5Proxy: + case QNetworkProxy::HttpProxy: + account->setProxyHostName(proxySettings._host); + account->setProxyPort(proxySettings._port); + account->setProxyNeedsAuth(proxySettings._needsAuth == WizardProxySettingsDialog::ProxyAuthentication::AuthenticationRequired); + if (account->proxyNeedsAuth()) { + account->setProxyUser(proxySettings._user); + account->setProxyPassword(proxySettings._password); + } + + break; + } // And also reset the QSslConfiguration, for the same reason (#6832) // Here the client certificate is added, if any. Later it'll be in HttpCredentials diff --git a/src/gui/owncloudsetupwizard.h b/src/gui/owncloudsetupwizard.h index af09ee2123..cdc64001fe 100644 --- a/src/gui/owncloudsetupwizard.h +++ b/src/gui/owncloudsetupwizard.h @@ -17,7 +17,7 @@ #include "theme.h" #include "networkjobs.h" -#include "wizard/owncloudwizardcommon.h" +#include "wizard/wizardproxysettingsdialog.h" namespace OCC { @@ -43,7 +43,7 @@ signals: void ownCloudWizardDone(int); private slots: - void slotCheckServer(const QString &); + void slotCheckServer(const QUrl &serverURL, const OCC::WizardProxySettingsDialog::WizardProxySettings &proxySettings); void slotSystemProxyLookupDone(const QNetworkProxy &proxy); void slotFindServer(); diff --git a/src/gui/wizard/owncloudsetuppage.cpp b/src/gui/wizard/owncloudsetuppage.cpp index e8a7b76abe..f504f2cc68 100644 --- a/src/gui/wizard/owncloudsetuppage.cpp +++ b/src/gui/wizard/owncloudsetuppage.cpp @@ -25,7 +25,7 @@ #include "wizard/owncloudwizardcommon.h" #include "wizard/owncloudsetuppage.h" #include "wizard/owncloudconnectionmethoddialog.h" -#include "wizard/slideshow.h" +#include "wizard/wizardproxysettingsdialog.h" #include "theme.h" #include "account.h" #include "config.h" @@ -190,8 +190,13 @@ void OwncloudSetupPage::slotUrlEditFinished() void OwncloudSetupPage::slotSetProxySettings() { - _proxySettingsDialog = new WizardProxySettings{QUrl::fromUserInput(_ui.leUrl->fullText()), this}; - _proxySettingsDialog->show(); + if (!_proxySettingsDialog) { + _proxySettingsDialog = new WizardProxySettingsDialog{QUrl::fromUserInput(_ui.leUrl->fullText()), _proxySettings, this}; + + connect(_proxySettingsDialog, &WizardProxySettingsDialog::proxySettingsAccepted, this, [this] (const OCC::WizardProxySettingsDialog::WizardProxySettings &proxySettings) { _proxySettings = proxySettings;}); + } + + _proxySettingsDialog->open(); } bool OwncloudSetupPage::isComplete() const @@ -291,8 +296,8 @@ bool OwncloudSetupPage::validatePage() { if (!_authTypeKnown) { slotUrlEditFinished(); - QString u = url(); - QUrl qurl(u); + const auto urlString = url(); + const auto qurl = QUrl::fromUserInput(urlString); if (!qurl.isValid() || qurl.host().isEmpty()) { setErrorString(tr("Server address does not seem to be valid"), false); return false; @@ -303,7 +308,7 @@ bool OwncloudSetupPage::validatePage() startSpinner(); emit completeChanged(); - emit determineAuthType(u); + Q_EMIT determineAuthType(qurl, _proxySettings); return false; } else { // connecting is running @@ -328,7 +333,7 @@ void OwncloudSetupPage::setErrorString(const QString &err, bool retryHTTPonly) } else { if (retryHTTPonly) { const auto urlString = url(); - QUrl url(urlString); + auto url = QUrl::fromUserInput(urlString); if (url.scheme() == "https") { // Ask the user how to proceed when connecting to a https:// URL fails. // It is possible that the server is secured with client-side TLS certificates, diff --git a/src/gui/wizard/owncloudsetuppage.h b/src/gui/wizard/owncloudsetuppage.h index 4edd1dd764..b5a0ccf6a7 100644 --- a/src/gui/wizard/owncloudsetuppage.h +++ b/src/gui/wizard/owncloudsetuppage.h @@ -9,17 +9,13 @@ #include -#include "wizard/owncloudwizardcommon.h" #include "wizard/owncloudwizard.h" #include "../addcertificatedialog.h" -#include "wizard/owncloudconnectionmethoddialog.h" -#include "wizard/wizardproxysettings.h" +#include "wizard/wizardproxysettingsdialog.h" #include "ui_owncloudsetupnocredspage.h" -#include "config.h" - class QLabel; class QVariant; class QProgressIndicator; @@ -65,7 +61,7 @@ protected slots: void setupCustomization(); signals: - void determineAuthType(const QString &); + void determineAuthType(const QUrl &serverURL, const OCC::WizardProxySettingsDialog::WizardProxySettings &proxySettings); private: void setLogo(); @@ -87,7 +83,8 @@ private: OwncloudWizard *_ocWizard; AddCertificateDialog *addCertDial = nullptr; - WizardProxySettings *_proxySettingsDialog = nullptr; + WizardProxySettingsDialog *_proxySettingsDialog = nullptr; + WizardProxySettingsDialog::WizardProxySettings _proxySettings; QMetaObject::Connection _proxyButtonIsConnected; // Grab the forceLoginV2-setting from the wizard diff --git a/src/gui/wizard/owncloudwizard.h b/src/gui/wizard/owncloudwizard.h index 76e41ede3a..c84840854f 100644 --- a/src/gui/wizard/owncloudwizard.h +++ b/src/gui/wizard/owncloudwizard.h @@ -15,6 +15,7 @@ #include "libsync/configfile.h" #include "networkjobs.h" #include "wizard/owncloudwizardcommon.h" +#include "wizard/wizardproxysettingsdialog.h" #include "accountfwd.h" namespace OCC { @@ -94,7 +95,7 @@ public slots: signals: void clearPendingRequests(); - void determineAuthType(const QString &); + void determineAuthType(const QUrl &serverURL, const OCC::WizardProxySettingsDialog::WizardProxySettings &proxySettings); void connectToOCUrl(const QString &); void createLocalAndRemoteFolders(const QString &, const QString &); // make sure to connect to this, rather than finished(int)!! diff --git a/src/gui/wizard/wizardproxysettings.cpp b/src/gui/wizard/wizardproxysettingsdialog.cpp similarity index 53% rename from src/gui/wizard/wizardproxysettings.cpp rename to src/gui/wizard/wizardproxysettingsdialog.cpp index 9f296aff01..a97d49c02c 100644 --- a/src/gui/wizard/wizardproxysettings.cpp +++ b/src/gui/wizard/wizardproxysettingsdialog.cpp @@ -3,7 +3,7 @@ * SPDX-License-Identifier: GPL-2.0-or-later */ -#include "wizardproxysettings.h" +#include "wizardproxysettingsdialog.h" #include #include @@ -12,9 +12,12 @@ namespace OCC { Q_LOGGING_CATEGORY(lcWizardProxySettings, "nextcloud.gui.wizard.proxysettings", QtInfoMsg) -WizardProxySettings::WizardProxySettings(QUrl serverURL, QWidget *parent) +WizardProxySettingsDialog::WizardProxySettingsDialog(QUrl serverURL, + WizardProxySettings proxySettings, + QWidget *parent) : QDialog(parent) - , _serverURL(std::move(serverURL)) + , _serverURL{std::move(serverURL)} + , _settings{std::move(proxySettings)} { _ui.setupUi(this); @@ -38,37 +41,68 @@ WizardProxySettings::WizardProxySettings(QUrl serverURL, QWidget *parent) connect(_ui.authRequiredcheckBox, &QAbstractButton::toggled, _ui.authWidgets, &QWidget::setEnabled); connect(_ui.manualProxyRadioButton, &QAbstractButton::toggled, _ui.manualSettings, &QWidget::setVisible); - connect(_ui.manualProxyRadioButton, &QAbstractButton::toggled, this, &WizardProxySettings::validateProxySettings); + connect(_ui.manualProxyRadioButton, &QAbstractButton::toggled, this, &WizardProxySettingsDialog::validateProxySettings); - connect(_ui.typeComboBox, static_cast(&QComboBox::currentIndexChanged), this, &WizardProxySettings::validateProxySettings); - connect(_ui.hostLineEdit, &QLineEdit::editingFinished, this, &WizardProxySettings::validateProxySettings); - connect(_ui.userLineEdit, &QLineEdit::editingFinished, this, &WizardProxySettings::validateProxySettings); - connect(_ui.passwordLineEdit, &QLineEdit::editingFinished, this, &WizardProxySettings::validateProxySettings); - connect(_ui.portSpinBox, &QAbstractSpinBox::editingFinished, this, &WizardProxySettings::validateProxySettings); - connect(_ui.authRequiredcheckBox, &QAbstractButton::toggled, this, &WizardProxySettings::validateProxySettings); + connect(_ui.typeComboBox, static_cast(&QComboBox::currentIndexChanged), this, &WizardProxySettingsDialog::validateProxySettings); + connect(_ui.hostLineEdit, &QLineEdit::editingFinished, this, &WizardProxySettingsDialog::validateProxySettings); + connect(_ui.userLineEdit, &QLineEdit::editingFinished, this, &WizardProxySettingsDialog::validateProxySettings); + connect(_ui.passwordLineEdit, &QLineEdit::editingFinished, this, &WizardProxySettingsDialog::validateProxySettings); + connect(_ui.portSpinBox, &QAbstractSpinBox::editingFinished, this, &WizardProxySettingsDialog::validateProxySettings); + connect(_ui.authRequiredcheckBox, &QAbstractButton::toggled, this, &WizardProxySettingsDialog::validateProxySettings); // Warn about empty proxy host - connect(_ui.hostLineEdit, &QLineEdit::textChanged, this, &WizardProxySettings::checkEmptyProxyHost); - connect(_ui.hostLineEdit, &QLineEdit::textChanged, this, &WizardProxySettings::validateProxySettings); + connect(_ui.hostLineEdit, &QLineEdit::textChanged, this, &WizardProxySettingsDialog::checkEmptyProxyHost); + connect(_ui.hostLineEdit, &QLineEdit::textChanged, this, &WizardProxySettingsDialog::validateProxySettings); - connect(_ui.userLineEdit, &QLineEdit::textChanged, this, &WizardProxySettings::checkEmptyProxyCredentials); - connect(_ui.passwordLineEdit, &QLineEdit::textChanged, this, &WizardProxySettings::checkEmptyProxyCredentials); - connect(_ui.authRequiredcheckBox, &QAbstractButton::toggled, this, &WizardProxySettings::checkEmptyProxyCredentials); + connect(_ui.userLineEdit, &QLineEdit::textChanged, this, &WizardProxySettingsDialog::checkEmptyProxyCredentials); + connect(_ui.passwordLineEdit, &QLineEdit::textChanged, this, &WizardProxySettingsDialog::checkEmptyProxyCredentials); + connect(_ui.authRequiredcheckBox, &QAbstractButton::toggled, this, &WizardProxySettingsDialog::checkEmptyProxyCredentials); connect(_ui.buttonBox, &QDialogButtonBox::accepted, - this, &WizardProxySettings::settingsDone); + this, &WizardProxySettingsDialog::settingsDone); connect(_ui.buttonBox, &QDialogButtonBox::rejected, - this, &WizardProxySettings::reject); + this, &WizardProxySettingsDialog::reject); checkEmptyProxyHost(); checkAccountLocalhost(); - _ui.noProxyRadioButton->setChecked(true); - _ui.noProxyRadioButton->setFocus(); - _ui.manualSettings->setVisible(false); + if (!_settings._user.isEmpty()) { + _ui.userLineEdit->setText(_settings._user); + } + if (!_settings._password.isEmpty()) { + _ui.passwordLineEdit->setText(_settings._password); + } + if (!_settings._host.isEmpty()) { + _ui.hostLineEdit->setText(_settings._host); + } + + _ui.authRequiredcheckBox->setChecked(_settings._needsAuth != ProxyAuthentication::NoAuthentication); + + switch (_settings._proxyType) + { + case QNetworkProxy::NoProxy: + _ui.noProxyRadioButton->setChecked(true); + _ui.noProxyRadioButton->setFocus(); + _ui.manualSettings->setVisible(false); + break; + case QNetworkProxy::ProxyType::DefaultProxy: + _ui.systemProxyRadioButton->setChecked(true); + _ui.systemProxyRadioButton->setFocus(); + _ui.manualSettings->setVisible(false); + break; + case QNetworkProxy::Socks5Proxy: + case QNetworkProxy::HttpProxy: + _ui.manualProxyRadioButton->setChecked(true); + _ui.manualProxyRadioButton->setFocus(); + _ui.manualSettings->setVisible(true); + break; + case QNetworkProxy::HttpCachingProxy: + case QNetworkProxy::FtpCachingProxy: + break; + } } -void WizardProxySettings::checkEmptyProxyHost() +void WizardProxySettingsDialog::checkEmptyProxyHost() { if (_ui.hostLineEdit->isEnabled() && _ui.hostLineEdit->text().isEmpty()) { _ui.hostLineEdit->setStyleSheet("border: 1px solid red"); @@ -77,7 +111,7 @@ void WizardProxySettings::checkEmptyProxyHost() } } -void WizardProxySettings::checkEmptyProxyCredentials() +void WizardProxySettingsDialog::checkEmptyProxyCredentials() { if (!_ui.authRequiredcheckBox->isChecked()) { _ui.userLineEdit->setStyleSheet(QString()); @@ -98,7 +132,7 @@ void WizardProxySettings::checkEmptyProxyCredentials() } } -void WizardProxySettings::checkAccountLocalhost() +void WizardProxySettingsDialog::checkAccountLocalhost() { auto visible = false; if (_ui.manualProxyRadioButton->isChecked()) { @@ -111,34 +145,34 @@ void WizardProxySettings::checkAccountLocalhost() _ui.labelLocalhost->setVisible(visible); } -void WizardProxySettings::validateProxySettings() +void WizardProxySettingsDialog::validateProxySettings() { checkEmptyProxyHost(); - _user = _ui.userLineEdit->text(); - _password = _ui.passwordLineEdit->text(); - _host = _ui.hostLineEdit->text(); - _port = _ui.portSpinBox->value(); - _needsAuth = _ui.authRequiredcheckBox->isChecked() ? ProxyAuthentication::AuthenticationRequired : ProxyAuthentication::NoAuthentication; + _settings._user = _ui.userLineEdit->text(); + _settings._password = _ui.passwordLineEdit->text(); + _settings._host = _ui.hostLineEdit->text(); + _settings._port = _ui.portSpinBox->value(); + _settings._needsAuth = _ui.authRequiredcheckBox->isChecked() ? ProxyAuthentication::AuthenticationRequired : ProxyAuthentication::NoAuthentication; - _proxyType = QNetworkProxy::NoProxy; + _settings._proxyType = QNetworkProxy::NoProxy; _valid = false; if (_ui.noProxyRadioButton->isChecked()) { - _proxyType = QNetworkProxy::NoProxy; + _settings._proxyType = QNetworkProxy::NoProxy; _valid = true; } else if (_ui.systemProxyRadioButton->isChecked()) { - _proxyType = QNetworkProxy::DefaultProxy; + _settings._proxyType = QNetworkProxy::DefaultProxy; _valid = true; } else if (_ui.manualProxyRadioButton->isChecked()) { - _proxyType = _ui.typeComboBox->itemData(_ui.typeComboBox->currentIndex()).value(); + _settings._proxyType = _ui.typeComboBox->itemData(_ui.typeComboBox->currentIndex()).value(); _valid = true; - if (_host.isEmpty()) { - _proxyType = QNetworkProxy::NoProxy; + if (_settings._host.isEmpty()) { + _settings._proxyType = QNetworkProxy::NoProxy; _valid = false; } - if (_ui.authRequiredcheckBox->isChecked() && (_user.isEmpty() || _password.isEmpty())) { - _proxyType = QNetworkProxy::NoProxy; + if (_ui.authRequiredcheckBox->isChecked() && (_settings._user.isEmpty() || _settings._password.isEmpty())) { + _settings._proxyType = QNetworkProxy::NoProxy; _valid = false; } } @@ -149,9 +183,9 @@ void WizardProxySettings::validateProxySettings() } } -void WizardProxySettings::settingsDone() +void WizardProxySettingsDialog::settingsDone() { - Q_EMIT proxySettingsAccepted(_user, _password, _host, _port, _needsAuth, _proxyType); + Q_EMIT proxySettingsAccepted(_settings); accept(); } diff --git a/src/gui/wizard/wizardproxysettings.h b/src/gui/wizard/wizardproxysettingsdialog.h similarity index 51% rename from src/gui/wizard/wizardproxysettings.h rename to src/gui/wizard/wizardproxysettingsdialog.h index 9305d8f725..ad30d841a8 100644 --- a/src/gui/wizard/wizardproxysettings.h +++ b/src/gui/wizard/wizardproxysettingsdialog.h @@ -12,7 +12,7 @@ namespace OCC { -class WizardProxySettings : public QDialog +class WizardProxySettingsDialog : public QDialog { Q_OBJECT public: @@ -21,15 +21,22 @@ public: NoAuthentication, }; - explicit WizardProxySettings(QUrl serverURL, QWidget *parent = nullptr); + struct WizardProxySettings + { + QString _user; + QString _password; + QString _host; + quint16 _port; + ProxyAuthentication _needsAuth = ProxyAuthentication::NoAuthentication; + QNetworkProxy::ProxyType _proxyType = QNetworkProxy::NoProxy; + }; + + explicit WizardProxySettingsDialog(QUrl serverURL, + WizardProxySettings proxySettings, + QWidget *parent = nullptr); Q_SIGNALS: - void proxySettingsAccepted(QString user, - QString password, - QString host, - int port, - WizardProxySettings::ProxyAuthentication needsAuth, - QNetworkProxy::ProxyType proxyType); + void proxySettingsAccepted(const OCC::WizardProxySettingsDialog::WizardProxySettings &proxySettings); private Q_SLOTS: /// Red marking of host field if empty and enabled @@ -50,12 +57,7 @@ private: bool _valid = false; - QString _user; - QString _password; - QString _host; - int _port; - ProxyAuthentication _needsAuth = ProxyAuthentication::NoAuthentication; - QNetworkProxy::ProxyType _proxyType = QNetworkProxy::NoProxy; + WizardProxySettings _settings; }; } From ac3c391bcff35ddbb01b03278182b4fd7a39eea4 Mon Sep 17 00:00:00 2001 From: Matthieu Gallien Date: Tue, 26 Aug 2025 11:07:09 +0200 Subject: [PATCH 5/7] fix: fix typo in dialog title Signed-off-by: Matthieu Gallien --- src/gui/wizard/wizardproxysettingsdialog.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/wizard/wizardproxysettingsdialog.cpp b/src/gui/wizard/wizardproxysettingsdialog.cpp index a97d49c02c..f29c610693 100644 --- a/src/gui/wizard/wizardproxysettingsdialog.cpp +++ b/src/gui/wizard/wizardproxysettingsdialog.cpp @@ -22,7 +22,7 @@ WizardProxySettingsDialog::WizardProxySettingsDialog(QUrl serverURL, _ui.setupUi(this); setWindowModality(Qt::WindowModal); - setWindowTitle(tr("Proxy Settigs", "Dialog window title for proxy settings")); + setWindowTitle(tr("Proxy Settings", "Dialog window title for proxy settings")); _ui.hostLineEdit->setPlaceholderText(tr("Hostname of proxy server")); _ui.userLineEdit->setPlaceholderText(tr("Username for proxy server")); From 20e705ee481119080a987e8440a479609a5771d7 Mon Sep 17 00:00:00 2001 From: Matthieu Gallien Date: Tue, 26 Aug 2025 11:13:59 +0200 Subject: [PATCH 6/7] fix: ensure up to date proxy settings dialog when opening it also ensure we properly check the state of the dialog when needed and only when needed Signed-off-by: Matthieu Gallien --- src/gui/wizard/owncloudsetuppage.cpp | 3 ++ src/gui/wizard/wizardproxysettingsdialog.cpp | 40 ++++++++++++++------ src/gui/wizard/wizardproxysettingsdialog.h | 6 +++ 3 files changed, 37 insertions(+), 12 deletions(-) diff --git a/src/gui/wizard/owncloudsetuppage.cpp b/src/gui/wizard/owncloudsetuppage.cpp index f504f2cc68..25e7f76fd6 100644 --- a/src/gui/wizard/owncloudsetuppage.cpp +++ b/src/gui/wizard/owncloudsetuppage.cpp @@ -194,6 +194,9 @@ void OwncloudSetupPage::slotSetProxySettings() _proxySettingsDialog = new WizardProxySettingsDialog{QUrl::fromUserInput(_ui.leUrl->fullText()), _proxySettings, this}; connect(_proxySettingsDialog, &WizardProxySettingsDialog::proxySettingsAccepted, this, [this] (const OCC::WizardProxySettingsDialog::WizardProxySettings &proxySettings) { _proxySettings = proxySettings;}); + } else { + _proxySettingsDialog->setServerUrl(QUrl::fromUserInput(_ui.leUrl->fullText())); + _proxySettingsDialog->setProxySettings(_proxySettings); } _proxySettingsDialog->open(); diff --git a/src/gui/wizard/wizardproxysettingsdialog.cpp b/src/gui/wizard/wizardproxysettingsdialog.cpp index f29c610693..241ae5a868 100644 --- a/src/gui/wizard/wizardproxysettingsdialog.cpp +++ b/src/gui/wizard/wizardproxysettingsdialog.cpp @@ -16,8 +16,6 @@ WizardProxySettingsDialog::WizardProxySettingsDialog(QUrl serverURL, WizardProxySettings proxySettings, QWidget *parent) : QDialog(parent) - , _serverURL{std::move(serverURL)} - , _settings{std::move(proxySettings)} { _ui.setupUi(this); @@ -44,27 +42,41 @@ WizardProxySettingsDialog::WizardProxySettingsDialog(QUrl serverURL, connect(_ui.manualProxyRadioButton, &QAbstractButton::toggled, this, &WizardProxySettingsDialog::validateProxySettings); connect(_ui.typeComboBox, static_cast(&QComboBox::currentIndexChanged), this, &WizardProxySettingsDialog::validateProxySettings); - connect(_ui.hostLineEdit, &QLineEdit::editingFinished, this, &WizardProxySettingsDialog::validateProxySettings); - connect(_ui.userLineEdit, &QLineEdit::editingFinished, this, &WizardProxySettingsDialog::validateProxySettings); - connect(_ui.passwordLineEdit, &QLineEdit::editingFinished, this, &WizardProxySettingsDialog::validateProxySettings); - connect(_ui.portSpinBox, &QAbstractSpinBox::editingFinished, this, &WizardProxySettingsDialog::validateProxySettings); connect(_ui.authRequiredcheckBox, &QAbstractButton::toggled, this, &WizardProxySettingsDialog::validateProxySettings); // Warn about empty proxy host - connect(_ui.hostLineEdit, &QLineEdit::textChanged, this, &WizardProxySettingsDialog::checkEmptyProxyHost); connect(_ui.hostLineEdit, &QLineEdit::textChanged, this, &WizardProxySettingsDialog::validateProxySettings); - - connect(_ui.userLineEdit, &QLineEdit::textChanged, this, &WizardProxySettingsDialog::checkEmptyProxyCredentials); - connect(_ui.passwordLineEdit, &QLineEdit::textChanged, this, &WizardProxySettingsDialog::checkEmptyProxyCredentials); - connect(_ui.authRequiredcheckBox, &QAbstractButton::toggled, this, &WizardProxySettingsDialog::checkEmptyProxyCredentials); + connect(_ui.userLineEdit, &QLineEdit::textChanged, this, &WizardProxySettingsDialog::validateProxySettings); + connect(_ui.passwordLineEdit, &QLineEdit::textChanged, this, &WizardProxySettingsDialog::validateProxySettings); + connect(_ui.portSpinBox, &QSpinBox::valueChanged, this, &WizardProxySettingsDialog::validateProxySettings); + connect(_ui.authRequiredcheckBox, &QAbstractButton::toggled, this, &WizardProxySettingsDialog::validateProxySettings); connect(_ui.buttonBox, &QDialogButtonBox::accepted, this, &WizardProxySettingsDialog::settingsDone); connect(_ui.buttonBox, &QDialogButtonBox::rejected, this, &WizardProxySettingsDialog::reject); - checkEmptyProxyHost(); + setServerUrl(std::move(serverURL)); + setProxySettings(std::move(proxySettings)); +} + +void WizardProxySettingsDialog::setServerUrl(QUrl serverUrl) +{ + if (_serverURL == serverUrl) { + return; + } + + _serverURL = std::move(serverUrl); checkAccountLocalhost(); +} + +void WizardProxySettingsDialog::setProxySettings(WizardProxySettings proxySettings) +{ + if (_settings == proxySettings) { + return; + } + + _settings = std::move(proxySettings); if (!_settings._user.isEmpty()) { _ui.userLineEdit->setText(_settings._user); @@ -100,6 +112,8 @@ WizardProxySettingsDialog::WizardProxySettingsDialog(QUrl serverURL, case QNetworkProxy::FtpCachingProxy: break; } + + validateProxySettings(); } void WizardProxySettingsDialog::checkEmptyProxyHost() @@ -148,6 +162,8 @@ void WizardProxySettingsDialog::checkAccountLocalhost() void WizardProxySettingsDialog::validateProxySettings() { checkEmptyProxyHost(); + checkEmptyProxyCredentials(); + checkAccountLocalhost(); _settings._user = _ui.userLineEdit->text(); _settings._password = _ui.passwordLineEdit->text(); diff --git a/src/gui/wizard/wizardproxysettingsdialog.h b/src/gui/wizard/wizardproxysettingsdialog.h index ad30d841a8..01dd921369 100644 --- a/src/gui/wizard/wizardproxysettingsdialog.h +++ b/src/gui/wizard/wizardproxysettingsdialog.h @@ -29,12 +29,18 @@ public: quint16 _port; ProxyAuthentication _needsAuth = ProxyAuthentication::NoAuthentication; QNetworkProxy::ProxyType _proxyType = QNetworkProxy::NoProxy; + + bool operator == (const WizardProxySettings &other) const = default; }; explicit WizardProxySettingsDialog(QUrl serverURL, WizardProxySettings proxySettings, QWidget *parent = nullptr); + void setServerUrl(QUrl serverUrl); + + void setProxySettings(WizardProxySettings proxySettings); + Q_SIGNALS: void proxySettingsAccepted(const OCC::WizardProxySettingsDialog::WizardProxySettings &proxySettings); From 130455ec4974c7d62c81bda7ee54fc209ecce183 Mon Sep 17 00:00:00 2001 From: Matthieu Gallien Date: Tue, 26 Aug 2025 12:13:56 +0200 Subject: [PATCH 7/7] fix: ensure proxy settings are visible only when needed when a build is configured without the network proxy feature, ensure we do not show any UI related to network proxy settings in the new account wizard Signed-off-by: Matthieu Gallien --- config.h.in | 2 +- src/gui/wizard/owncloudsetuppage.cpp | 39 +++++++++++++++++++--------- src/gui/wizard/owncloudsetuppage.h | 2 ++ src/gui/wizard/owncloudwizard.cpp | 6 ++++- src/libsync/theme.cpp | 10 +------ src/libsync/theme.h | 10 +++++-- 6 files changed, 44 insertions(+), 25 deletions(-) diff --git a/config.h.in b/config.h.in index e4f46791fb..8d6096ccf1 100644 --- a/config.h.in +++ b/config.h.in @@ -35,7 +35,7 @@ #define APPLICATION_URI_HANDLER_SCHEME "@APPLICATION_URI_HANDLER_SCHEME@" #cmakedefine01 ENFORCE_VIRTUAL_FILES_SYNC_FOLDER #cmakedefine01 DISABLE_VIRTUAL_FILES_SYNC_FOLDER -#cmakedefine DO_NOT_USE_PROXY "@DO_NOT_USE_PROXY@" +#cmakedefine01 DO_NOT_USE_PROXY #cmakedefine ENFORCE_SINGLE_ACCOUNT "@ENFORCE_SINGLE_ACCOUNT@" #cmakedefine01 APPLICATION_DISPLAY_LEGACY_IMPORT_DIALOG #cmakedefine01 DISABLE_ACCOUNT_MIGRATION diff --git a/src/gui/wizard/owncloudsetuppage.cpp b/src/gui/wizard/owncloudsetuppage.cpp index 25e7f76fd6..616d6527b2 100644 --- a/src/gui/wizard/owncloudsetuppage.cpp +++ b/src/gui/wizard/owncloudsetuppage.cpp @@ -97,11 +97,7 @@ void OwncloudSetupPage::setupServerAddressDescriptionLabel() void OwncloudSetupPage::setProxySettingsButtonEnabled(bool enable) { - if (!wizard()) { - return; - } - - const auto proxySettingsButton = wizard()->button(QWizard::CustomButton3); + const auto proxySettingsButton = getProxySettingsButton(); if (!proxySettingsButton) { return; @@ -110,6 +106,30 @@ void OwncloudSetupPage::setProxySettingsButtonEnabled(bool enable) proxySettingsButton->setEnabled(enable); } +void OwncloudSetupPage::setProxySettingsButtonVisible(bool visible) +{ + const auto proxySettingsButton = getProxySettingsButton(); + + if (!proxySettingsButton) { + return; + } + + proxySettingsButton->setVisible(visible); +} + +QAbstractButton *OwncloudSetupPage::getProxySettingsButton() const +{ + auto result = static_cast(nullptr); + + if (!wizard()) { + return result; + } + + result = wizard()->button(QWizard::CustomButton3); + + return result; +} + void OwncloudSetupPage::setServerUrl(const QString &newUrl) { _ocWizard->setRegistration(false); @@ -224,8 +244,6 @@ void OwncloudSetupPage::initializePage() _ui.leUrl->setFocus(); - setProxySettingsButtonEnabled(false); - const auto isServerUrlOverridden = !Theme::instance()->overrideServerUrl().isEmpty(); if (isServerUrlOverridden && !Theme::instance()->forceOverrideServerUrl()) { // If the url is overwritten but we don't force to use that url @@ -244,16 +262,13 @@ void OwncloudSetupPage::initializePage() setVisible(false); } + setProxySettingsButtonEnabled(false); ensureProxySettingsButtonIsConnected(); } void OwncloudSetupPage::ensureProxySettingsButtonIsConnected() { - if (!wizard()) { - return; - } - - const auto proxySettingsButton = wizard()->button(QWizard::CustomButton3); + const auto proxySettingsButton = getProxySettingsButton(); if (!proxySettingsButton) { return; diff --git a/src/gui/wizard/owncloudsetuppage.h b/src/gui/wizard/owncloudsetuppage.h index b5a0ccf6a7..549487064a 100644 --- a/src/gui/wizard/owncloudsetuppage.h +++ b/src/gui/wizard/owncloudsetuppage.h @@ -69,6 +69,8 @@ private: void setupServerAddressDescriptionLabel(); void setProxySettingsButtonEnabled(bool enable); + void setProxySettingsButtonVisible(bool visible); + [[nodiscard]] QAbstractButton* getProxySettingsButton() const; void ensureProxySettingsButtonIsConnected(); Ui_OwncloudSetupPage _ui{}; diff --git a/src/gui/wizard/owncloudwizard.cpp b/src/gui/wizard/owncloudwizard.cpp index a7243659fc..126ee2b5bb 100644 --- a/src/gui/wizard/owncloudwizard.cpp +++ b/src/gui/wizard/owncloudwizard.cpp @@ -355,7 +355,11 @@ void OwncloudWizard::slotCurrentPageChanged(int id) setButtonLayout({QWizard::CustomButton2, QWizard::Stretch, QWizard::CustomButton1, QWizard::FinishButton}); setNextButtonAsDefault(); } else if (id == WizardCommon::Page_ServerSetup) { - setButtonLayout({QWizard::BackButton, QWizard::Stretch, QWizard::CustomButton3, QWizard::NextButton}); + if constexpr (Theme::doNotUseProxy()) { + setButtonLayout({QWizard::BackButton, QWizard::Stretch, QWizard::NextButton}); + } else { + setButtonLayout({QWizard::BackButton, QWizard::Stretch, QWizard::CustomButton3, QWizard::NextButton}); + } setNextButtonAsDefault(); } else { setButtonLayout({QWizard::BackButton, QWizard::Stretch, QWizard::NextButton}); diff --git a/src/libsync/theme.cpp b/src/libsync/theme.cpp index cf7271963d..b93a688107 100644 --- a/src/libsync/theme.cpp +++ b/src/libsync/theme.cpp @@ -5,7 +5,6 @@ */ #include "theme.h" -#include "config.h" #include "common/utility.h" #include "version.h" #include "configfile.h" @@ -505,14 +504,7 @@ bool Theme::forbidBadSSL() const #endif } -bool Theme::doNotUseProxy() const -{ -#ifdef DO_NOT_USE_PROXY - return true; -#else - return false; -#endif -} + QString Theme::forceConfigAuthType() const { diff --git a/src/libsync/theme.h b/src/libsync/theme.h index 53d9df3b50..e2abad23cb 100644 --- a/src/libsync/theme.h +++ b/src/libsync/theme.h @@ -7,11 +7,14 @@ #ifndef _THEME_H #define _THEME_H +#include "config.h" + +#include "syncresult.h" + #include #include #include #include -#include "syncresult.h" class QString; class QObject; @@ -275,7 +278,10 @@ public: * * When true, the app always connects to the server directly */ - [[nodiscard]] bool doNotUseProxy() const; + [[nodiscard]] constexpr static bool doNotUseProxy() + { + return DO_NOT_USE_PROXY; + } /** * This is only useful when previous version had a different overrideServerUrl