Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nextcloud/desktop.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFelix Weilbach <felix.weilbach@nextcloud.com>2021-03-10 14:54:43 +0300
committerGitHub <noreply@github.com>2021-03-10 14:54:43 +0300
commitb5cf820b423fe4ffc67d948ae801a8f76f853cd0 (patch)
treef1a72af4aa3eed9c91bb79eff92c85b05304b0b7
parent344b28d2f8698985111b25d886727abe56c773e6 (diff)
parente0b7ef15b207f59d73884f8e1c12a206803c5c40 (diff)
Merge pull request #2895 from nextcloud/wizard_ui_improvements
Improve wizard ui
-rw-r--r--NEXTCLOUD.cmake3
-rw-r--r--config.h.in1
-rw-r--r--src/gui/CMakeLists.txt3
-rw-r--r--src/gui/application.cpp3
-rw-r--r--src/gui/owncloudsetupwizard.cpp9
-rw-r--r--src/gui/wizard/flow2authcredspage.cpp5
-rw-r--r--src/gui/wizard/flow2authwidget.cpp52
-rw-r--r--src/gui/wizard/flow2authwidget.h1
-rw-r--r--src/gui/wizard/flow2authwidget.ui179
-rw-r--r--src/gui/wizard/linklabel.cpp58
-rw-r--r--src/gui/wizard/linklabel.h46
-rw-r--r--src/gui/wizard/owncloudadvancedsetuppage.cpp176
-rw-r--r--src/gui/wizard/owncloudadvancedsetuppage.h13
-rw-r--r--src/gui/wizard/owncloudadvancedsetuppage.ui978
-rw-r--r--src/gui/wizard/owncloudsetupnocredspage.ui470
-rw-r--r--src/gui/wizard/owncloudsetuppage.cpp140
-rw-r--r--src/gui/wizard/owncloudsetuppage.h2
-rw-r--r--src/gui/wizard/owncloudwizard.cpp92
-rw-r--r--src/gui/wizard/owncloudwizard.h6
-rw-r--r--src/gui/wizard/owncloudwizardcommon.cpp13
-rw-r--r--src/gui/wizard/owncloudwizardcommon.h8
-rw-r--r--src/gui/wizard/webview.ui6
-rw-r--r--src/gui/wizard/webviewpage.cpp40
-rw-r--r--src/gui/wizard/webviewpage.h6
-rw-r--r--src/gui/wizard/welcomepage.cpp120
-rw-r--r--src/gui/wizard/welcomepage.h54
-rw-r--r--src/gui/wizard/welcomepage.ui229
-rw-r--r--src/libsync/nextcloudtheme.cpp2
-rw-r--r--src/libsync/theme.cpp42
-rw-r--r--src/libsync/theme.h6
-rw-r--r--test/CMakeLists.txt2
-rw-r--r--test/testtheme.cpp111
-rw-r--r--test/themeutils.cpp40
-rw-r--r--test/themeutils.h34
-rw-r--r--theme.qrc30
-rw-r--r--theme/black/external.pngbin0 -> 1135 bytes
-rw-r--r--theme/black/external.svg1
-rw-r--r--theme/black/external@2x.pngbin0 -> 2096 bytes
-rw-r--r--theme/black/folder.pngbin0 -> 346 bytes
-rw-r--r--theme/black/folder.svg1
-rw-r--r--theme/black/folder@2x.pngbin0 -> 569 bytes
-rw-r--r--theme/black/wizard-files.pngbin0 -> 1278 bytes
-rw-r--r--theme/black/wizard-files.svg1
-rw-r--r--theme/black/wizard-files@2x.pngbin0 -> 2524 bytes
-rw-r--r--theme/black/wizard-groupware.pngbin0 -> 1778 bytes
-rw-r--r--theme/black/wizard-groupware.svg1
-rw-r--r--theme/black/wizard-groupware@2x.pngbin0 -> 3734 bytes
-rw-r--r--theme/black/wizard-nextcloud.pngbin0 -> 3410 bytes
-rw-r--r--theme/black/wizard-nextcloud.svg81
-rw-r--r--theme/black/wizard-nextcloud@2x.pngbin0 -> 7396 bytes
-rw-r--r--theme/black/wizard-talk.pngbin0 -> 1954 bytes
-rw-r--r--theme/black/wizard-talk.svg1
-rw-r--r--theme/black/wizard-talk@2x.pngbin0 -> 4303 bytes
-rw-r--r--theme/colored/external.pngbin0 -> 1439 bytes
-rw-r--r--theme/colored/external.svg1
-rw-r--r--theme/colored/external@2x.pngbin0 -> 2487 bytes
-rw-r--r--theme/colored/folder.pngbin0 -> 426 bytes
-rw-r--r--theme/colored/folder.svg2
-rw-r--r--theme/colored/folder@2x.pngbin0 -> 659 bytes
-rw-r--r--theme/colored/wizard-files.pngbin1697 -> 1681 bytes
-rw-r--r--theme/colored/wizard-files@2x.pngbin3201 -> 3185 bytes
-rw-r--r--theme/colored/wizard-groupware.pngbin2476 -> 2460 bytes
-rw-r--r--theme/colored/wizard-groupware@2x.pngbin5042 -> 5026 bytes
-rw-r--r--theme/colored/wizard-nextcloud.pngbin2633 -> 5228 bytes
-rw-r--r--theme/colored/wizard-nextcloud.svg82
-rw-r--r--theme/colored/wizard-nextcloud@2x.pngbin5377 -> 11010 bytes
-rw-r--r--theme/colored/wizard-talk.pngbin2992 -> 2976 bytes
-rw-r--r--theme/colored/wizard-talk@2x.pngbin6161 -> 6145 bytes
-rw-r--r--theme/colored/wizard_logo.svg2
-rw-r--r--theme/sync-arrow.svg1
-rw-r--r--theme/white/external.pngbin0 -> 1255 bytes
-rw-r--r--theme/white/external.svg1
-rw-r--r--theme/white/external@2x.pngbin0 -> 2256 bytes
-rw-r--r--theme/white/folder.pngbin0 -> 364 bytes
-rw-r--r--theme/white/folder.svg2
-rw-r--r--theme/white/folder@2x.pngbin0 -> 590 bytes
-rw-r--r--theme/white/wizard-files.pngbin0 -> 1444 bytes
-rw-r--r--theme/white/wizard-files.svg1
-rw-r--r--theme/white/wizard-files@2x.pngbin0 -> 2777 bytes
-rw-r--r--theme/white/wizard-groupware.pngbin0 -> 2003 bytes
-rw-r--r--theme/white/wizard-groupware.svg1
-rw-r--r--theme/white/wizard-groupware@2x.pngbin0 -> 4278 bytes
-rw-r--r--theme/white/wizard-nextcloud.pngbin0 -> 4075 bytes
-rw-r--r--theme/white/wizard-nextcloud.svg81
-rw-r--r--theme/white/wizard-nextcloud@2x.pngbin0 -> 9394 bytes
-rw-r--r--theme/white/wizard-talk.pngbin0 -> 2301 bytes
-rw-r--r--theme/white/wizard-talk.svg1
-rw-r--r--theme/white/wizard-talk@2x.pngbin0 -> 5282 bytes
88 files changed, 2433 insertions, 808 deletions
diff --git a/NEXTCLOUD.cmake b/NEXTCLOUD.cmake
index e9edb7b80..82f1bd4b7 100644
--- a/NEXTCLOUD.cmake
+++ b/NEXTCLOUD.cmake
@@ -34,7 +34,8 @@ option( WITH_PROVIDERS "Build with providers list" ON )
## Theming options
-set( APPLICATION_WIZARD_HEADER_BACKGROUND_COLOR "#0082c9" CACHE STRING "Hex color of the wizard header background")
+set(NEXTCLOUD_BACKGROUND_COLOR "#0082c9" CACHE STRING "Default Nextcloud background color")
+set( APPLICATION_WIZARD_HEADER_BACKGROUND_COLOR ${NEXTCLOUD_BACKGROUND_COLOR} CACHE STRING "Hex color of the wizard header background")
set( APPLICATION_WIZARD_HEADER_TITLE_COLOR "#ffffff" CACHE STRING "Hex color of the text in the wizard header")
option( APPLICATION_WIZARD_USE_CUSTOM_LOGO "Use the logo from ':/client/theme/colored/wizard_logo.(png|svg)' else the default application icon is used" ON )
diff --git a/config.h.in b/config.h.in
index d69788752..13d4cdf08 100644
--- a/config.h.in
+++ b/config.h.in
@@ -25,6 +25,7 @@
#cmakedefine APPLICATION_SERVER_URL_ENFORCE "@APPLICATION_SERVER_URL_ENFORCE@"
#cmakedefine LINUX_APPLICATION_ID "@LINUX_APPLICATION_ID@"
#cmakedefine APPLICATION_WIZARD_HEADER_BACKGROUND_COLOR "@APPLICATION_WIZARD_HEADER_BACKGROUND_COLOR@"
+#cmakedefine NEXTCLOUD_BACKGROUND_COLOR "@NEXTCLOUD_BACKGROUND_COLOR@"
#cmakedefine APPLICATION_WIZARD_HEADER_TITLE_COLOR "@APPLICATION_WIZARD_HEADER_TITLE_COLOR@"
#cmakedefine APPLICATION_WIZARD_USE_CUSTOM_LOGO "@APPLICATION_WIZARD_USE_CUSTOM_LOGO@"
#cmakedefine APPLICATION_VIRTUALFILE_SUFFIX "@APPLICATION_VIRTUALFILE_SUFFIX@"
diff --git a/src/gui/CMakeLists.txt b/src/gui/CMakeLists.txt
index 346114074..13cde2ff9 100644
--- a/src/gui/CMakeLists.txt
+++ b/src/gui/CMakeLists.txt
@@ -51,6 +51,7 @@ set(client_UI_SRCS
wizard/owncloudsetupnocredspage.ui
wizard/owncloudwizardresultpage.ui
wizard/webview.ui
+ wizard/welcomepage.ui
)
set(client_SRCS
@@ -134,6 +135,8 @@ set(client_SRCS
wizard/webviewpage.cpp
wizard/webview.cpp
wizard/slideshow.cpp
+ wizard/welcomepage.cpp
+ wizard/linklabel.cpp
)
IF(BUILD_UPDATER)
diff --git a/src/gui/application.cpp b/src/gui/application.cpp
index 2813ae45f..d23be5c14 100644
--- a/src/gui/application.cpp
+++ b/src/gui/application.cpp
@@ -338,9 +338,6 @@ Application::Application(int &argc, char **argv)
FolderMan::instance()->setupFolders();
_proxy.setupQtProxyFromConfig(); // folders have to be defined first, than we set up the Qt proxy.
- // Enable word wrapping of QInputDialog (#4197)
- setStyleSheet("QInputDialog QLabel { qproperty-wordWrap:1; }");
-
connect(AccountManager::instance(), &AccountManager::accountAdded,
this, &Application::slotAccountStateAdded);
connect(AccountManager::instance(), &AccountManager::accountRemoved,
diff --git a/src/gui/owncloudsetupwizard.cpp b/src/gui/owncloudsetupwizard.cpp
index ba7fecd29..51c727208 100644
--- a/src/gui/owncloudsetupwizard.cpp
+++ b/src/gui/owncloudsetupwizard.cpp
@@ -116,7 +116,7 @@ void OwncloudSetupWizard::startWizard()
// if its a relative path, prepend with users home dir, otherwise use as absolute path
if (!QDir(localFolder).isAbsolute()) {
- localFolder = QDir::homePath() + QDir::separator() + localFolder;
+ localFolder = QDir::homePath() + QLatin1Char('/') + localFolder;
}
_ocWizard->setProperty("localFolder", localFolder);
@@ -131,7 +131,12 @@ void OwncloudSetupWizard::startWizard()
_ocWizard->setRemoteFolder(_remoteFolder);
- _ocWizard->setStartId(WizardCommon::Page_ServerSetup);
+#ifdef WITH_PROVIDERS
+ const auto startPage = WizardCommon::Page_Welcome;
+#else // WITH_PROVIDERS
+ const auto startPage = WizardCommon::Page_ServerSetup;
+#endif // WITH_PROVIDERS
+ _ocWizard->setStartId(startPage);
_ocWizard->restart();
diff --git a/src/gui/wizard/flow2authcredspage.cpp b/src/gui/wizard/flow2authcredspage.cpp
index 33bced583..e03b9a50f 100644
--- a/src/gui/wizard/flow2authcredspage.cpp
+++ b/src/gui/wizard/flow2authcredspage.cpp
@@ -33,9 +33,6 @@ Flow2AuthCredsPage::Flow2AuthCredsPage()
{
_layout = new QVBoxLayout(this);
- setTitle(WizardCommon::titleTemplate().arg(tr("Connect to %1").arg(Theme::instance()->appNameGUI())));
- setSubTitle(WizardCommon::subTitleTemplate().arg(tr("Login in your browser (Login Flow v2)")));
-
_flow2AuthWidget = new Flow2AuthWidget();
_layout->addWidget(_flow2AuthWidget);
@@ -59,6 +56,8 @@ void Flow2AuthCredsPage::initializePage()
// Don't hide the wizard (avoid user confusion)!
//wizard()->hide();
+
+ _flow2AuthWidget->slotStyleChanged();
}
void OCC::Flow2AuthCredsPage::cleanupPage()
diff --git a/src/gui/wizard/flow2authwidget.cpp b/src/gui/wizard/flow2authwidget.cpp
index 86a6ebb4a..04b78d5cc 100644
--- a/src/gui/wizard/flow2authwidget.cpp
+++ b/src/gui/wizard/flow2authwidget.cpp
@@ -17,6 +17,8 @@
#include "common/utility.h"
#include "account.h"
#include "wizard/owncloudwizardcommon.h"
+#include "theme.h"
+#include "linklabel.h"
#include "QProgressIndicator.h"
@@ -34,13 +36,23 @@ Flow2AuthWidget::Flow2AuthWidget(QWidget *parent)
WizardCommon::initErrorLabel(_ui.errorLabel);
_ui.errorLabel->setTextFormat(Qt::RichText);
- connect(_ui.openLinkButton, &QCommandLinkButton::clicked, this, &Flow2AuthWidget::slotOpenBrowser);
- connect(_ui.copyLinkButton, &QCommandLinkButton::clicked, this, &Flow2AuthWidget::slotCopyLinkToClipboard);
+ connect(_ui.openLinkLabel, &LinkLabel::clicked, this, &Flow2AuthWidget::slotOpenBrowser);
+ connect(_ui.copyLinkLabel, &LinkLabel::clicked, this, &Flow2AuthWidget::slotCopyLinkToClipboard);
- _ui.horizontalLayout->addWidget(_progressIndi);
+ auto sizePolicy = _progressIndi->sizePolicy();
+ sizePolicy.setRetainSizeWhenHidden(true);
+ _progressIndi->setSizePolicy(sizePolicy);
+
+ _ui.progressLayout->addWidget(_progressIndi);
stopSpinner(false);
+}
- customizeStyle();
+void Flow2AuthWidget::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 Flow2AuthWidget::startAuth(Account *account)
@@ -160,24 +172,24 @@ void Flow2AuthWidget::slotStatusChanged(Flow2Auth::PollStatus status, int second
void Flow2AuthWidget::startSpinner()
{
- _ui.horizontalLayout->setEnabled(true);
+ _ui.progressLayout->setEnabled(true);
_ui.statusLabel->setVisible(true);
_progressIndi->setVisible(true);
_progressIndi->startAnimation();
- _ui.openLinkButton->setEnabled(false);
- _ui.copyLinkButton->setEnabled(false);
+ _ui.openLinkLabel->setEnabled(false);
+ _ui.copyLinkLabel->setEnabled(false);
}
void Flow2AuthWidget::stopSpinner(bool showStatusLabel)
{
- _ui.horizontalLayout->setEnabled(false);
+ _ui.progressLayout->setEnabled(false);
_ui.statusLabel->setVisible(showStatusLabel);
_progressIndi->setVisible(false);
_progressIndi->stopAnimation();
- _ui.openLinkButton->setEnabled(_statusUpdateSkipCount == 0);
- _ui.copyLinkButton->setEnabled(_statusUpdateSkipCount == 0);
+ _ui.openLinkLabel->setEnabled(_statusUpdateSkipCount == 0);
+ _ui.copyLinkLabel->setEnabled(_statusUpdateSkipCount == 0);
}
void Flow2AuthWidget::slotStyleChanged()
@@ -187,8 +199,24 @@ void Flow2AuthWidget::slotStyleChanged()
void Flow2AuthWidget::customizeStyle()
{
- if(_progressIndi)
- _progressIndi->setColor(QGuiApplication::palette().color(QPalette::Text));
+ setLogo();
+
+ if (_progressIndi) {
+ const auto isDarkBackground = Theme::isDarkColor(palette().window().color());
+ if (isDarkBackground) {
+ _progressIndi->setColor(Qt::white);
+ } else {
+ _progressIndi->setColor(Qt::black);
+ }
+ }
+
+ _ui.openLinkLabel->setText(tr("Reopen Browser"));
+ _ui.openLinkLabel->setAlignment(Qt::AlignCenter);
+
+ _ui.copyLinkLabel->setText(tr("Copy Link"));
+ _ui.copyLinkLabel->setAlignment(Qt::AlignCenter);
+
+ WizardCommon::customizeHintLabel(_ui.statusLabel);
}
} // namespace OCC
diff --git a/src/gui/wizard/flow2authwidget.h b/src/gui/wizard/flow2authwidget.h
index 8c13806b1..90095c79c 100644
--- a/src/gui/wizard/flow2authwidget.h
+++ b/src/gui/wizard/flow2authwidget.h
@@ -60,6 +60,7 @@ private:
void startSpinner();
void stopSpinner(bool showStatusLabel);
void customizeStyle();
+ void setLogo();
QProgressIndicator *_progressIndi;
int _statusUpdateSkipCount = 0;
diff --git a/src/gui/wizard/flow2authwidget.ui b/src/gui/wizard/flow2authwidget.ui
index 57f23186d..44961ddae 100644
--- a/src/gui/wizard/flow2authwidget.ui
+++ b/src/gui/wizard/flow2authwidget.ui
@@ -27,44 +27,138 @@
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
- <widget class="QLabel" name="label">
- <property name="text">
- <string>Please switch to your browser to proceed.</string>
- </property>
- <property name="wordWrap">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLabel" name="errorLabel">
- <property name="text">
- <string>An error occurred while connecting. Please try again.</string>
+ <spacer name="verticalSpacer_3">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
</property>
- <property name="textFormat">
- <enum>Qt::PlainText</enum>
+ <property name="sizeType">
+ <enum>QSizePolicy::Expanding</enum>
</property>
- </widget>
- </item>
- <item>
- <widget class="QCommandLinkButton" name="openLinkButton">
- <property name="text">
- <string>Re-open Browser</string>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>80</height>
+ </size>
</property>
- </widget>
+ </spacer>
</item>
<item>
- <widget class="QCommandLinkButton" name="copyLinkButton">
- <property name="font">
- <font>
- <weight>50</weight>
- <bold>false</bold>
- </font>
+ <layout class="QVBoxLayout" name="verticalLayout_3">
+ <property name="topMargin">
+ <number>0</number>
</property>
- <property name="text">
- <string>Copy link</string>
+ <property name="bottomMargin">
+ <number>0</number>
</property>
- </widget>
+ <item>
+ <widget class="QLabel" name="logoLabel">
+ <property name="text">
+ <string>Logo</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="label">
+ <property name="font">
+ <font>
+ <pointsize>12</pointsize>
+ <weight>75</weight>
+ <bold>true</bold>
+ </font>
+ </property>
+ <property name="text">
+ <string>Switch to your browser to connect your account</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="statusLabel">
+ <property name="text">
+ <string notr="true">Status</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <spacer name="horizontalSpacer_2">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <layout class="QVBoxLayout" name="verticalLayout_2">
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="OCC::LinkLabel" name="copyLinkLabel" native="true"/>
+ </item>
+ <item>
+ <widget class="OCC::LinkLabel" name="openLinkLabel" native="true"/>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QLabel" name="errorLabel">
+ <property name="text">
+ <string>An error occurred while connecting. Please try again.</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="progressLayout"/>
+ </item>
+ </layout>
</item>
<item>
<spacer name="verticalSpacer_2">
@@ -80,19 +174,6 @@
</spacer>
</item>
<item>
- <widget class="QLabel" name="statusLabel">
- <property name="text">
- <string notr="true">TextLabel</string>
- </property>
- <property name="alignment">
- <set>Qt::AlignCenter</set>
- </property>
- </widget>
- </item>
- <item>
- <layout class="QHBoxLayout" name="horizontalLayout"/>
- </item>
- <item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
@@ -100,13 +181,21 @@
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
- <height>107</height>
+ <height>80</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
+ <customwidgets>
+ <customwidget>
+ <class>OCC::LinkLabel</class>
+ <extends>QWidget</extends>
+ <header>wizard/linklabel.h</header>
+ <container>1</container>
+ </customwidget>
+ </customwidgets>
<resources/>
<connections/>
</ui>
diff --git a/src/gui/wizard/linklabel.cpp b/src/gui/wizard/linklabel.cpp
new file mode 100644
index 000000000..918e9dc7f
--- /dev/null
+++ b/src/gui/wizard/linklabel.cpp
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2021 by Felix Weilbach <felix.weilbach@nextcloud.com>
+ *
+ * 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 "linklabel.h"
+#include "guiutility.h"
+
+namespace OCC {
+
+LinkLabel::LinkLabel(QWidget *parent) : QLabel(parent)
+{
+
+}
+
+void LinkLabel::setUrl(const QUrl &url)
+{
+ this->url = url;
+}
+
+void LinkLabel::enterEvent(QEvent * /*event*/)
+{
+ setFontUnderline(true);
+ setCursor(Qt::PointingHandCursor);
+}
+
+void LinkLabel::leaveEvent(QEvent * /*event*/)
+{
+ setFontUnderline(false);
+ setCursor(Qt::ArrowCursor);
+}
+
+void LinkLabel::mouseReleaseEvent(QMouseEvent * /*event*/)
+{
+ if (url.isValid()) {
+ Utility::openBrowser(url);
+ }
+
+ emit clicked();
+}
+
+void LinkLabel::setFontUnderline(bool value)
+{
+ auto labelFont = font();
+ labelFont.setUnderline(value);
+ setFont(labelFont);
+}
+
+}
diff --git a/src/gui/wizard/linklabel.h b/src/gui/wizard/linklabel.h
new file mode 100644
index 000000000..eb4ba0f81
--- /dev/null
+++ b/src/gui/wizard/linklabel.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2021 by Felix Weilbach <felix.weilbach@nextcloud.com>
+ *
+ * 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 <QLabel>
+#include <QUrl>
+
+namespace OCC {
+
+class LinkLabel : public QLabel
+{
+ Q_OBJECT
+public:
+ explicit LinkLabel(QWidget *parent = nullptr);
+
+ void setUrl(const QUrl &url);
+
+signals:
+ void clicked();
+
+protected:
+ void enterEvent(QEvent *event) override;
+
+ void leaveEvent(QEvent *event) override;
+
+ void mouseReleaseEvent(QMouseEvent *event) override;
+
+private:
+ void setFontUnderline(bool value);
+
+ QUrl url;
+};
+
+}
diff --git a/src/gui/wizard/owncloudadvancedsetuppage.cpp b/src/gui/wizard/owncloudadvancedsetuppage.cpp
index b3d45bb61..9249ea45a 100644
--- a/src/gui/wizard/owncloudadvancedsetuppage.cpp
+++ b/src/gui/wizard/owncloudadvancedsetuppage.cpp
@@ -19,6 +19,7 @@
#include <QTimer>
#include <QStorageInfo>
#include <QMessageBox>
+#include <QJsonObject>
#include "QProgressIndicator.h"
@@ -32,27 +33,31 @@
#include <folderman.h>
#include "creds/abstractcredentials.h"
#include "networkjobs.h"
+#include "wizard/owncloudwizard.h"
namespace OCC {
-OwncloudAdvancedSetupPage::OwncloudAdvancedSetupPage()
+OwncloudAdvancedSetupPage::OwncloudAdvancedSetupPage(OwncloudWizard *wizard)
: QWizardPage()
, _progressIndi(new QProgressIndicator(this))
+ , _ocWizard(wizard)
{
_ui.setupUi(this);
- Theme *theme = Theme::instance();
- setTitle(WizardCommon::titleTemplate().arg(tr("Connect to %1").arg(theme->appNameGUI())));
- setSubTitle(WizardCommon::subTitleTemplate().arg(tr("Setup local folder options")));
+ setupResoultionWidget();
registerField(QLatin1String("OCSyncFromScratch"), _ui.cbSyncFromScratch);
+ auto sizePolicy = _progressIndi->sizePolicy();
+ sizePolicy.setRetainSizeWhenHidden(true);
+ _progressIndi->setSizePolicy(sizePolicy);
+
_ui.resultLayout->addWidget(_progressIndi);
stopSpinner();
setupCustomization();
connect(_ui.pbSelectLocalFolder, &QAbstractButton::clicked, this, &OwncloudAdvancedSetupPage::slotSelectFolder);
- setButtonText(QWizard::NextButton, tr("Connect …"));
+ setButtonText(QWizard::NextButton, tr("Connect"));
connect(_ui.rSyncEverything, &QAbstractButton::clicked, this, &OwncloudAdvancedSetupPage::slotSyncEverythingClicked);
connect(_ui.rSelectiveSync, &QAbstractButton::clicked, this, &OwncloudAdvancedSetupPage::slotSelectiveSyncClicked);
@@ -65,13 +70,11 @@ OwncloudAdvancedSetupPage::OwncloudAdvancedSetupPage()
});
connect(_ui.bSelectiveSync, &QAbstractButton::clicked, this, &OwncloudAdvancedSetupPage::slotSelectiveSyncClicked);
- QIcon appIcon = theme->applicationIcon();
- _ui.lServerIcon->setText(QString());
- _ui.lServerIcon->setPixmap(appIcon.pixmap(48));
- _ui.lLocalIcon->setText(QString());
-
- // TO DO: File doesn't exist anymore - unneccessary or replacement needed?
- _ui.lLocalIcon->setPixmap(QPixmap(Theme::hidpiFileName(":/client/theme/folder-sync.png")));
+ const auto theme = Theme::instance();
+ const auto appIcon = theme->applicationIcon();
+ const auto appIconSize = Theme::isHidpi() ? 128 : 64;
+
+ _ui.lServerIcon->setPixmap(appIcon.pixmap(appIconSize));
if (theme->wizardHideExternalStorageConfirmationCheckbox()) {
_ui.confCheckBoxExternal->hide();
@@ -106,6 +109,11 @@ void OwncloudAdvancedSetupPage::setupCustomization()
variant = theme->customMedia(Theme::oCSetupBottom);
WizardCommon::setupCustomMedia(variant, _ui.bottomLabel);
+
+ WizardCommon::customizeHintLabel(_ui.lFreeSpace);
+ WizardCommon::customizeHintLabel(_ui.lSyncEverythingSizeLabel);
+ WizardCommon::customizeHintLabel(_ui.lSelectiveSyncSizeLabel);
+ WizardCommon::customizeHintLabel(_ui.serverAddressLabel);
}
bool OwncloudAdvancedSetupPage::isComplete() const
@@ -158,6 +166,69 @@ void OwncloudAdvancedSetupPage::initializePage()
_ui.confCheckBoxSize->setChecked(newFolderLimit.first);
_ui.confSpinBox->setValue(newFolderLimit.second);
_ui.confCheckBoxExternal->setChecked(cfgFile.confirmExternalStorage());
+
+ fetchUserAvatar();
+ fetchUserData();
+
+ customizeStyle();
+
+ auto nextButton = qobject_cast<QPushButton *>(_ocWizard->button(QWizard::NextButton));
+ if (nextButton) {
+ nextButton->setDefault(true);
+ }
+}
+
+void OwncloudAdvancedSetupPage::fetchUserAvatar()
+{
+ // Reset user avatar
+ const auto appIcon = Theme::instance()->applicationIcon();
+ _ui.lServerIcon->setPixmap(appIcon.pixmap(48));
+ // Fetch user avatar
+ const auto account = _ocWizard->account();
+ auto avatarSize = 64;
+ if (Theme::isHidpi()) {
+ avatarSize *= 2;
+ }
+ const auto avatarJob = new AvatarJob(account, account->davUser(), avatarSize, this);
+ avatarJob->setTimeout(20 * 1000);
+ QObject::connect(avatarJob, &AvatarJob::avatarPixmap, this, [this](const QImage &avatarImage) {
+ if (avatarImage.isNull()) {
+ return;
+ }
+ const auto avatarPixmap = QPixmap::fromImage(AvatarJob::makeCircularAvatar(avatarImage));
+ _ui.lServerIcon->setPixmap(avatarPixmap);
+ });
+ avatarJob->start();
+}
+
+void OwncloudAdvancedSetupPage::fetchUserData()
+{
+ const auto account = _ocWizard->account();
+
+ // Fetch user data
+ const auto userJob = new JsonApiJob(account, QLatin1String("ocs/v1.php/cloud/user"), this);
+ userJob->setTimeout(20 * 1000);
+ connect(userJob, &JsonApiJob::jsonReceived, this, [this](const QJsonDocument &json) {
+ const auto objData = json.object().value("ocs").toObject().value("data").toObject();
+ const auto displayName = objData.value("display-name").toString();
+ _ui.userNameLabel->setText(displayName);
+ });
+ userJob->start();
+
+ const auto serverUrl = account->url().toString();
+ setServerAddressLabelUrl(serverUrl);
+ const auto userName = account->davDisplayName();
+ _ui.userNameLabel->setText(userName);
+}
+
+void OwncloudAdvancedSetupPage::setServerAddressLabelUrl(const QUrl &url)
+{
+ if (!url.isValid()) {
+ return;
+ }
+
+ const auto prettyUrl = url.toString().mid(url.scheme().size() + 3); // + 3 because we need to remove ://
+ _ui.serverAddressLabel->setText(prettyUrl);
}
// Called if the user changes the user- or url field. Adjust the texts and
@@ -172,7 +243,8 @@ void OwncloudAdvancedSetupPage::updateStatus()
QString t;
- _ui.pbSelectLocalFolder->setText(QDir::toNativeSeparators(locFolder));
+ setLocalFolderPushButtonPath(locFolder);
+
if (dataChanged()) {
if (_remoteFolder.isEmpty() || _remoteFolder == QLatin1String("/")) {
t = "";
@@ -185,20 +257,18 @@ void OwncloudAdvancedSetupPage::updateStatus()
const bool dirNotEmpty(QDir(locFolder).entryList(QDir::AllEntries | QDir::NoDotAndDotDot).count() > 0);
if (dirNotEmpty) {
- t += tr("<p><small><strong>Warning:</strong> The local folder is not empty. "
- "Pick a resolution!</small></p>");
+ t += tr("Warning: The local folder is not empty. Pick a resolution!");
}
- _ui.resolutionWidget->setVisible(dirNotEmpty);
+ setResolutionGuiVisible(dirNotEmpty);
} else {
- _ui.resolutionWidget->setVisible(false);
+ setResolutionGuiVisible(false);
}
QString lfreeSpaceStr = Utility::octetsToString(availableLocalSpace());
- _ui.lFreeSpace->setText(QString(tr("Free space: %1")).arg(lfreeSpaceStr));
+ _ui.lFreeSpace->setText(QString(tr("%1 free space", "%1 gets replaced with the size and a matching unit. Example: 3 MB or 5 GB")).arg(lfreeSpaceStr));
_ui.syncModeLabel->setText(t);
_ui.syncModeLabel->setFixedHeight(_ui.syncModeLabel->sizeHint().height());
- wizard()->resize(wizard()->sizeHint());
qint64 rSpace = _ui.rSyncEverything->isChecked() ? _rSize : _rSelectedSize;
@@ -211,6 +281,13 @@ void OwncloudAdvancedSetupPage::updateStatus()
emit completeChanged();
}
+void OwncloudAdvancedSetupPage::setResolutionGuiVisible(bool value)
+{
+ _ui.syncModeLabel->setVisible(value);
+ _ui.rKeepLocal->setVisible(value);
+ _ui.cbSyncFromScratch->setVisible(value);
+}
+
/* obsolete */
bool OwncloudAdvancedSetupPage::dataChanged()
{
@@ -334,7 +411,7 @@ void OwncloudAdvancedSetupPage::slotSelectFolder()
{
QString dir = QFileDialog::getExistingDirectory(nullptr, tr("Local Sync Folder"), QDir::homePath());
if (!dir.isEmpty()) {
- _ui.pbSelectLocalFolder->setText(dir);
+ setLocalFolderPushButtonPath(dir);
wizard()->setProperty("localFolder", dir);
updateStatus();
}
@@ -344,6 +421,22 @@ void OwncloudAdvancedSetupPage::slotSelectFolder()
setErrorString(errorStr);
}
+
+void OwncloudAdvancedSetupPage::setLocalFolderPushButtonPath(const QString &path)
+{
+ const auto homeDir = QDir::homePath().endsWith('/') ? QDir::homePath() : QDir::homePath() + QLatin1Char('/');
+
+ if (!path.startsWith(homeDir)) {
+ _ui.pbSelectLocalFolder->setText(QDir::toNativeSeparators(path));
+ return;
+ }
+
+ auto prettyPath = path;
+ prettyPath.remove(0, homeDir.size());
+
+ _ui.pbSelectLocalFolder->setText(QDir::toNativeSeparators(prettyPath));
+}
+
void OwncloudAdvancedSetupPage::slotSelectiveSyncClicked()
{
AccountPtr acc = static_cast<OwncloudWizard *>(wizard())->account();
@@ -384,6 +477,8 @@ void OwncloudAdvancedSetupPage::slotSelectiveSyncClicked()
wizard()->setProperty("blacklist", _selectiveSyncBlacklist);
}
+ updateStatus();
+
});
dlg->open();
}
@@ -439,8 +534,25 @@ void OwncloudAdvancedSetupPage::slotStyleChanged()
void OwncloudAdvancedSetupPage::customizeStyle()
{
- if(_progressIndi)
- _progressIndi->setColor(QGuiApplication::palette().color(QPalette::Text));
+ if (_progressIndi) {
+ const auto isDarkBackground = Theme::isDarkColor(palette().window().color());
+ if (isDarkBackground) {
+ _progressIndi->setColor(Qt::white);
+ } else {
+ _progressIndi->setColor(Qt::black);
+ }
+ }
+
+ styleSyncLogo();
+ styleLocalFolderLabel();
+}
+
+void OwncloudAdvancedSetupPage::styleLocalFolderLabel()
+{
+ const auto backgroundColor = palette().window().color();
+ const auto folderIconFileName = Theme::instance()->isBranded() ? Theme::hidpiFileName("folder.png", backgroundColor)
+ : Theme::hidpiFileName(":/client/theme/colored/folder.png");
+ _ui.lLocal->setPixmap(folderIconFileName);
}
void OwncloudAdvancedSetupPage::setRadioChecked(QRadioButton *radio)
@@ -457,4 +569,24 @@ void OwncloudAdvancedSetupPage::setRadioChecked(QRadioButton *radio)
_ui.rVirtualFileSync->setCheckable(false);
}
+void OwncloudAdvancedSetupPage::styleSyncLogo()
+{
+ const auto syncArrowIcon = Theme::createColorAwareIcon(QLatin1String(":/client/theme/sync-arrow.svg"), palette());
+ _ui.syncLogoLabel->setPixmap(syncArrowIcon.pixmap(QSize(50, 50)));
+}
+
+void OwncloudAdvancedSetupPage::setupResoultionWidget()
+{
+ for (int i = 0; i < _ui.resolutionWidgetLayout->count(); ++i) {
+ auto widget = _ui.resolutionWidgetLayout->itemAt(i)->widget();
+ if (!widget) {
+ continue;
+ }
+
+ auto sizePolicy = widget->sizePolicy();
+ sizePolicy.setRetainSizeWhenHidden(true);
+ widget->setSizePolicy(sizePolicy);
+ }
+}
+
} // namespace OCC
diff --git a/src/gui/wizard/owncloudadvancedsetuppage.h b/src/gui/wizard/owncloudadvancedsetuppage.h
index 7fcde225a..8af948d9c 100644
--- a/src/gui/wizard/owncloudadvancedsetuppage.h
+++ b/src/gui/wizard/owncloudadvancedsetuppage.h
@@ -25,6 +25,8 @@ class QProgressIndicator;
namespace OCC {
+class OwncloudWizard;
+
/**
* @brief The OwncloudAdvancedSetupPage class
* @ingroup gui
@@ -33,7 +35,7 @@ class OwncloudAdvancedSetupPage : public QWizardPage
{
Q_OBJECT
public:
- OwncloudAdvancedSetupPage();
+ OwncloudAdvancedSetupPage(OwncloudWizard *wizard);
bool isComplete() const override;
void initializePage() override;
@@ -73,6 +75,14 @@ private:
qint64 availableLocalSpace() const;
QString checkLocalSpace(qint64 remoteSize) const;
void customizeStyle();
+ void setServerAddressLabelUrl(const QUrl &url);
+ void setLocalFolderPushButtonPath(const QString &path);
+ void styleSyncLogo();
+ void styleLocalFolderLabel();
+ void setResolutionGuiVisible(bool value);
+ void setupResoultionWidget();
+ void fetchUserAvatar();
+ void fetchUserData();
Ui_OwncloudAdvancedSetupPage _ui;
bool _checking = false;
@@ -83,6 +93,7 @@ private:
QStringList _selectiveSyncBlacklist;
qint64 _rSize = -1;
qint64 _rSelectedSize = -1;
+ OwncloudWizard *_ocWizard;
};
} // namespace OCC
diff --git a/src/gui/wizard/owncloudadvancedsetuppage.ui b/src/gui/wizard/owncloudadvancedsetuppage.ui
index 3b3b688dd..075de0840 100644
--- a/src/gui/wizard/owncloudadvancedsetuppage.ui
+++ b/src/gui/wizard/owncloudadvancedsetuppage.ui
@@ -11,7 +11,7 @@
</rect>
</property>
<property name="sizePolicy">
- <sizepolicy hsizetype="Maximum" vsizetype="Maximum">
+ <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
@@ -48,7 +48,7 @@
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
- <enum>QSizePolicy::Fixed</enum>
+ <enum>QSizePolicy::Expanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
@@ -59,9 +59,291 @@
</spacer>
</item>
<item>
- <layout class="QGridLayout" name="gridLayout">
- <item row="2" column="2">
- <spacer name="horizontalSpacer_2">
+ <layout class="QHBoxLayout" name="horizontalLayout_4">
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <spacer name="horizontalSpacer_12">
+ <property name="orientation">
+ <enum>Qt::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_3">
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <layout class="QVBoxLayout" name="verticalLayout_2">
+ <item>
+ <spacer name="verticalSpacer_5">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Expanding</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QLabel" name="lServerIcon">
+ <property name="text">
+ <string notr="true">Avatar</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="userNameLabel">
+ <property name="font">
+ <font>
+ <weight>75</weight>
+ <bold>true</bold>
+ </font>
+ </property>
+ <property name="text">
+ <string>User name</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="serverAddressLabel">
+ <property name="text">
+ <string>Server address</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="verticalSpacer_3">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Expanding</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_11">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Minimum</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QLabel" name="syncLogoLabel">
+ <property name="text">
+ <string>Sync Logo</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_6">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Minimum</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <layout class="QVBoxLayout" name="verticalLayout_5">
+ <item>
+ <spacer name="verticalSpacer_6">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Expanding</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QLabel" name="lLocal">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>&amp;Local Folder</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
+ <property name="buddy">
+ <cstring>pbSelectLocalFolder</cstring>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="localFolderDescriptionLabel">
+ <property name="font">
+ <font>
+ <weight>75</weight>
+ <bold>true</bold>
+ </font>
+ </property>
+ <property name="text">
+ <string>Local Folder</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <spacer name="horizontalSpacer_3">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Minimum</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>0</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="pbSelectLocalFolder">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string notr="true">pbSelectLocalFolder</string>
+ </property>
+ <property name="autoDefault">
+ <bool>true</bool>
+ </property>
+ <property name="default">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_4">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Minimum</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>0</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QLabel" name="lFreeSpace">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string notr="true">Free space</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="verticalSpacer">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Expanding</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_13">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
@@ -73,378 +355,428 @@
</property>
</spacer>
</item>
- <item row="0" column="1" colspan="2">
- <widget class="QWidget" name="wSyncStrategy" native="true">
- <layout class="QVBoxLayout" name="verticalLayout">
- <property name="leftMargin">
- <number>0</number>
- </property>
- <property name="rightMargin">
- <number>0</number>
- </property>
- <item>
- <layout class="QHBoxLayout" name="horizontalLayout_2">
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_2">
+ <property name="sizeConstraint">
+ <enum>QLayout::SetMinimumSize</enum>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <spacer name="horizontalSpacer_14">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <layout class="QVBoxLayout" name="verticalLayout_7">
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <layout class="QVBoxLayout" name="wSyncStrategy">
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_5">
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QRadioButton" name="rSyncEverything">
+ <property name="text">
+ <string>Synchronize everything from server</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="lSyncEverythingSizeLabel">
+ <property name="text">
+ <string notr="true">Size</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_2">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_6">
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <spacer name="horizontalSpacer_8">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Minimum</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="confCheckBoxSize">
+ <property name="text">
+ <string>Ask before syncing folders larger than</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QSpinBox" name="confSpinBox">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="focusPolicy">
+ <enum>Qt::StrongFocus</enum>
+ </property>
+ <property name="maximum">
+ <number>999999</number>
+ </property>
+ <property name="value">
+ <number>99</number>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="confTraillingSizeLabel">
+ <property name="text">
+ <string extracomment="Trailing part of &quot;Ask confirmation before syncing folder larger than&quot; ">MB</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_7">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_8">
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <spacer name="horizontalSpacer_9">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Minimum</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="confCheckBoxExternal">
+ <property name="text">
+ <string>Ask before syncing external storages</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_10">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_10">
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QRadioButton" name="rSelectiveSync">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="checkable">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="bSelectiveSync">
+ <property name="text">
+ <string>Choose what to sync</string>
+ </property>
+ <property name="autoDefault">
+ <bool>true</bool>
+ </property>
+ <property name="default">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="lSelectiveSyncSizeLabel">
+ <property name="text">
+ <string notr="true">TextLabel</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="lVirtualFileSync">
+ <item>
+ <widget class="QRadioButton" name="rVirtualFileSync">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string notr="true">Use virtual files !PLACEHOLDER!</string>
+ </property>
+ <property name="checkable">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_5">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QWidget" name="resolutionWidget" native="true">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <layout class="QVBoxLayout" name="resolutionWidgetLayout" stretch="0,0,0">
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <property name="sizeConstraint">
+ <enum>QLayout::SetMinimumSize</enum>
+ </property>
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>2</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
<item>
- <widget class="QRadioButton" name="rSyncEverything">
- <property name="text">
- <string>S&amp;ynchronize everything from server</string>
+ <widget class="QLabel" name="syncModeLabel">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
</property>
- <property name="checked">
- <bool>true</bool>
+ <property name="font">
+ <font>
+ <pointsize>9</pointsize>
+ <weight>75</weight>
+ <bold>true</bold>
+ </font>
+ </property>
+ <property name="lineWidth">
+ <number>1</number>
</property>
- </widget>
- </item>
- <item>
- <widget class="QLabel" name="lSyncEverythingSizeLabel">
<property name="text">
- <string notr="true">TextLabel</string>
+ <string notr="true">Status message</string>
</property>
<property name="textFormat">
- <enum>Qt::PlainText</enum>
+ <enum>Qt::AutoText</enum>
</property>
- </widget>
- </item>
- <item>
- <spacer name="horizontalSpacer_3">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>40</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- </layout>
- </item>
- <item>
- <layout class="QGridLayout" name="gridLayout_2">
- <property name="horizontalSpacing">
- <number>0</number>
- </property>
- <item row="0" column="0">
- <spacer name="horizontalSpacer_4">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
</property>
- <property name="sizeType">
- <enum>QSizePolicy::Minimum</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>10</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- <item row="0" column="1">
- <layout class="QHBoxLayout" name="horizontalLayout_3">
- <item>
- <widget class="QCheckBox" name="confCheckBoxSize">
- <property name="text">
- <string>Ask for confirmation before synchroni&amp;zing folders larger than</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QSpinBox" name="confSpinBox">
- <property name="maximum">
- <number>999999</number>
- </property>
- <property name="value">
- <number>99</number>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLabel" name="confTraillingSizeLabel">
- <property name="text">
- <string extracomment="Trailing part of &quot;Ask confirmation before syncing folder larger than&quot; ">MB</string>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item row="1" column="1">
- <widget class="QCheckBox" name="confCheckBoxExternal">
- <property name="text">
- <string>Ask for confirmation before synchronizing e&amp;xternal storages</string>
+ <property name="wordWrap">
+ <bool>false</bool>
</property>
</widget>
</item>
- </layout>
- </item>
- <item>
- <layout class="QHBoxLayout" name="horizontalLayout">
<item>
- <widget class="QRadioButton" name="rSelectiveSync">
+ <widget class="QRadioButton" name="rKeepLocal">
<property name="sizePolicy">
- <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
+ <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
- <string/>
- </property>
- <property name="checkable">
- <bool>false</bool>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QPushButton" name="bSelectiveSync">
- <property name="text">
- <string>Choose what to sync</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLabel" name="lSelectiveSyncSizeLabel">
- <property name="text">
- <string notr="true">TextLabel</string>
+ <string>Keep local data</string>
</property>
- <property name="textFormat">
- <enum>Qt::PlainText</enum>
+ <property name="checked">
+ <bool>true</bool>
</property>
</widget>
</item>
<item>
- <spacer name="horizontalSpacer">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>40</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- </layout>
- </item>
- <item>
- <layout class="QHBoxLayout" name="lVirtualFileSync">
- <item>
- <widget class="QRadioButton" name="rVirtualFileSync">
+ <widget class="QRadioButton" name="cbSyncFromScratch">
<property name="sizePolicy">
- <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
+ <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
+ <property name="toolTip">
+ <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;If this box is checked, existing content in the local folder will be erased to start a clean sync from the server.&lt;/p&gt;&lt;p&gt;Do not check this if the local content should be uploaded to the servers folder.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ </property>
<property name="text">
- <string notr="true">Use &amp;virtual files !PLACEHOLDER!</string>
+ <string>Erase local folder and start a clean sync</string>
</property>
<property name="checkable">
- <bool>false</bool>
+ <bool>true</bool>
</property>
</widget>
</item>
- <item>
- <spacer name="horizontalSpacer_5">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>40</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
</layout>
- </item>
- </layout>
- </widget>
- </item>
- <item row="2" column="0" rowspan="4">
- <layout class="QVBoxLayout" name="verticalLayout_3">
- <item>
- <widget class="QLabel" name="lLocalIcon">
- <property name="text">
- <string notr="true">TextLabel</string>
- </property>
- <property name="alignment">
- <set>Qt::AlignCenter</set>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLabel" name="lLocal">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Minimum" vsizetype="Preferred">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="text">
- <string>&amp;Local Folder</string>
- </property>
- <property name="alignment">
- <set>Qt::AlignCenter</set>
- </property>
- <property name="buddy">
- <cstring>pbSelectLocalFolder</cstring>
- </property>
</widget>
</item>
- <item>
- <spacer name="verticalSpacer_4">
- <property name="orientation">
- <enum>Qt::Vertical</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>20</width>
- <height>40</height>
- </size>
- </property>
- </spacer>
- </item>
</layout>
</item>
- <item row="2" column="1" rowspan="2">
- <widget class="QPushButton" name="pbSelectLocalFolder">
- <property name="sizePolicy">
- <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="text">
- <string notr="true">pbSelectLocalFolder</string>
- </property>
- </widget>
- </item>
- <item row="0" column="0">
- <layout class="QVBoxLayout" name="verticalLayout_2">
- <item>
- <widget class="QLabel" name="lServerIcon">
- <property name="text">
- <string notr="true">TextLabel</string>
- </property>
- <property name="alignment">
- <set>Qt::AlignCenter</set>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLabel" name="lServer">
- <property name="text">
- <string>Server</string>
- </property>
- <property name="alignment">
- <set>Qt::AlignCenter</set>
- </property>
- </widget>
- </item>
- <item>
- <spacer name="verticalSpacer_3">
- <property name="orientation">
- <enum>Qt::Vertical</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>20</width>
- <height>40</height>
- </size>
- </property>
- </spacer>
- </item>
- </layout>
- </item>
- <item row="5" column="1" colspan="2">
- <widget class="QWidget" name="resolutionWidget" native="true">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <layout class="QFormLayout" name="formLayout_2">
- <property name="sizeConstraint">
- <enum>QLayout::SetMinimumSize</enum>
- </property>
- <property name="fieldGrowthPolicy">
- <enum>QFormLayout::ExpandingFieldsGrow</enum>
- </property>
- <item row="1" column="0" colspan="2">
- <widget class="QRadioButton" name="radioButton">
- <property name="text">
- <string>&amp;Keep local data</string>
- </property>
- <property name="checked">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- <item row="2" column="0" colspan="2">
- <widget class="QRadioButton" name="cbSyncFromScratch">
- <property name="toolTip">
- <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;If this box is checked, existing content in the local folder will be erased to start a clean sync from the server.&lt;/p&gt;&lt;p&gt;Do not check this if the local content should be uploaded to the servers folder.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
- </property>
- <property name="text">
- <string>Start a &amp;clean sync (Erases the local folder!)</string>
- </property>
- <property name="checkable">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- </item>
- <item row="1" column="1">
- <spacer name="verticalSpacer">
+ <item>
+ <spacer name="horizontalSpacer_15">
<property name="orientation">
- <enum>Qt::Vertical</enum>
- </property>
- <property name="sizeType">
- <enum>QSizePolicy::MinimumExpanding</enum>
+ <enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
- <width>20</width>
- <height>40</height>
+ <width>40</width>
+ <height>20</height>
</size>
</property>
</spacer>
</item>
- <item row="4" column="1">
- <widget class="QLabel" name="lFreeSpace">
- <property name="text">
- <string notr="true">TextLabel</string>
- </property>
- </widget>
- </item>
</layout>
</item>
<item>
- <widget class="QLabel" name="errorLabel">
- <property name="text">
- <string notr="true">TextLabel</string>
+ <spacer name="verticalSpacer_4">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
</property>
- </widget>
+ <property name="sizeType">
+ <enum>QSizePolicy::Expanding</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
</item>
<item>
- <widget class="QLabel" name="syncModeLabel">
+ <widget class="QLabel" name="errorLabel">
<property name="text">
- <string notr="true">Status message</string>
- </property>
- <property name="textFormat">
- <enum>Qt::RichText</enum>
- </property>
- <property name="alignment">
- <set>Qt::AlignCenter</set>
- </property>
- <property name="wordWrap">
- <bool>true</bool>
+ <string notr="true">TextLabel</string>
</property>
</widget>
</item>
diff --git a/src/gui/wizard/owncloudsetupnocredspage.ui b/src/gui/wizard/owncloudsetupnocredspage.ui
index d3e62595e..d67873450 100644
--- a/src/gui/wizard/owncloudsetupnocredspage.ui
+++ b/src/gui/wizard/owncloudsetupnocredspage.ui
@@ -6,12 +6,12 @@
<rect>
<x>0</x>
<y>0</y>
- <width>802</width>
- <height>629</height>
+ <width>556</width>
+ <height>489</height>
</rect>
</property>
<property name="sizePolicy">
- <sizepolicy hsizetype="Preferred" vsizetype="Maximum">
+ <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
@@ -27,103 +27,85 @@
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
- <spacer name="verticalSpacer_5">
+ <widget class="QLabel" name="topLabel">
+ <property name="text">
+ <string>TextLabel</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
- <enum>QSizePolicy::MinimumExpanding</enum>
+ <enum>QSizePolicy::Expanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
- <height>20</height>
+ <height>80</height>
</size>
</property>
</spacer>
</item>
<item>
- <widget class="QLabel" name="topLabel">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="text">
- <string notr="true">TextLabel</string>
- </property>
- <property name="textFormat">
- <enum>Qt::RichText</enum>
- </property>
- <property name="alignment">
- <set>Qt::AlignCenter</set>
- </property>
- <property name="wordWrap">
- <bool>true</bool>
+ <layout class="QHBoxLayout" name="horizontalLayout_4">
+ <property name="topMargin">
+ <number>0</number>
</property>
- </widget>
- </item>
- <item>
- <layout class="QHBoxLayout" name="horizontalLayout_9">
<item>
- <widget class="QPushButton" name="prevButton">
- <property name="minimumSize">
- <size>
- <width>40</width>
- <height>0</height>
- </size>
+ <spacer name="horizontalSpacer_3">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
</property>
- <property name="maximumSize">
+ <property name="sizeHint" stdset="0">
<size>
- <width>40</width>
- <height>16777215</height>
+ <width>0</width>
+ <height>0</height>
</size>
</property>
- <property name="text">
- <string/>
- </property>
- <property name="flat">
- <bool>true</bool>
- </property>
- </widget>
+ </spacer>
</item>
<item>
- <widget class="OCC::SlideShow" name="slideShow" native="true">
- <property name="font">
- <font>
- <pointsize>12</pointsize>
- <weight>75</weight>
- <bold>true</bold>
- </font>
+ <widget class="QLabel" name="logoLabel">
+ <property name="text">
+ <string>Logo</string>
</property>
</widget>
</item>
<item>
- <widget class="QPushButton" name="nextButton">
- <property name="minimumSize">
- <size>
- <width>40</width>
- <height>0</height>
- </size>
+ <spacer name="horizontalSpacer_4">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
</property>
- <property name="maximumSize">
+ <property name="sizeHint" stdset="0">
<size>
- <width>40</width>
- <height>16777215</height>
+ <width>0</width>
+ <height>0</height>
</size>
</property>
- <property name="text">
- <string/>
- </property>
- <property name="flat">
- <bool>true</bool>
- </property>
- </widget>
+ </spacer>
</item>
</layout>
</item>
<item>
+ <spacer name="verticalSpacer_5">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Minimum</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
<widget class="QWidget" name="login" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Expanding">
@@ -143,38 +125,28 @@
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<layout class="QHBoxLayout" name="serverBox">
+ <property name="spacing">
+ <number>0</number>
+ </property>
<property name="sizeConstraint">
<enum>QLayout::SetDefaultConstraint</enum>
</property>
<item>
- <spacer name="horizontalSpacer">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeType">
- <enum>QSizePolicy::Preferred</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>40</width>
- <height>0</height>
- </size>
- </property>
- </spacer>
- </item>
- <item>
<layout class="QVBoxLayout" name="verticalLayout">
+ <property name="spacing">
+ <number>6</number>
+ </property>
<item>
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
- <enum>QSizePolicy::MinimumExpanding</enum>
+ <enum>QSizePolicy::Minimum</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
- <width>20</width>
+ <width>0</width>
<height>0</height>
</size>
</property>
@@ -182,74 +154,139 @@
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
+ <property name="topMargin">
+ <number>0</number>
+ </property>
<item>
- <widget class="QLabel" name="label_2">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Preferred" vsizetype="Ignored">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
+ <spacer name="horizontalSpacer_7">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
</property>
- <property name="text">
- <string>Server Address</string>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
</property>
- <property name="buddy">
- <cstring>leUrl</cstring>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QLabel" name="serverAddressLabel">
+ <property name="font">
+ <font>
+ <pointsize>12</pointsize>
+ <weight>75</weight>
+ <bold>true</bold>
+ </font>
+ </property>
+ <property name="text">
+ <string>Server address</string>
</property>
</widget>
</item>
<item>
- <widget class="OCC::PostfixLineEdit" name="leUrl">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
+ <spacer name="horizontalSpacer_8">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
</property>
- <property name="placeholderText">
- <string notr="true"/>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
</property>
- </widget>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_5">
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <spacer name="horizontalSpacer_2">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Expanding</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>80</width>
+ <height>0</height>
+ </size>
+ </property>
+ </spacer>
</item>
<item>
- <layout class="QHBoxLayout" name="resultLayout">
- <property name="spacing">
+ <layout class="QVBoxLayout" name="verticalLayout_5">
+ <property name="topMargin">
+ <number>8</number>
+ </property>
+ <property name="rightMargin">
<number>0</number>
</property>
+ <item>
+ <widget class="OCC::PostfixLineEdit" name="leUrl">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>200</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="placeholderText">
+ <string notr="true">https://try.nextcloud.com</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="serverAddressDescriptionLabel">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>This is the link to your %1 web interface when you open it in the browser.</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
</layout>
</item>
<item>
- <widget class="QLabel" name="urlLabel">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Expanding</enum>
</property>
- <property name="minimumSize">
+ <property name="sizeHint" stdset="0">
<size>
- <width>24</width>
- <height>24</height>
+ <width>80</width>
+ <height>0</height>
</size>
</property>
- <property name="text">
- <string/>
- </property>
- </widget>
+ </spacer>
</item>
</layout>
</item>
<item>
- <widget class="QLabel" name="addressDescriptionLabel">
- <property name="text">
- <string>This is the link to your %1 web interface when you open it in the browser.&lt;br/&gt;It looks like https://cloud.example.com or https://example.com/cloud</string>
- </property>
- <property name="wordWrap">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- <item>
<widget class="QLabel" name="errorLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
@@ -269,6 +306,9 @@
</widget>
</item>
<item>
+ <layout class="QHBoxLayout" name="progressLayout"/>
+ </item>
+ <item>
<spacer name="verticalSpacer_3">
<property name="orientation">
<enum>Qt::Vertical</enum>
@@ -278,7 +318,7 @@
</property>
<property name="sizeHint" stdset="0">
<size>
- <width>20</width>
+ <width>0</width>
<height>0</height>
</size>
</property>
@@ -286,22 +326,6 @@
</item>
</layout>
</item>
- <item>
- <spacer name="horizontalSpacer_2">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeType">
- <enum>QSizePolicy::Preferred</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>40</width>
- <height>0</height>
- </size>
- </property>
- </spacer>
- </item>
</layout>
</item>
</layout>
@@ -317,163 +341,26 @@
</property>
<property name="sizeHint" stdset="0">
<size>
- <width>20</width>
- <height>20</height>
+ <width>0</width>
+ <height>0</height>
</size>
</property>
</spacer>
</item>
<item>
- <layout class="QHBoxLayout" name="buttons" stretch="0,0,0,0">
- <property name="spacing">
- <number>6</number>
- </property>
- <property name="topMargin">
- <number>20</number>
+ <widget class="QLabel" name="bottomLabel">
+ <property name="text">
+ <string>TextLabel</string>
</property>
- <item>
- <spacer name="horizontalSpacer_3">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>40</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- <item>
- <widget class="QPushButton" name="createAccountButton">
- <property name="minimumSize">
- <size>
- <width>150</width>
- <height>0</height>
- </size>
- </property>
- <property name="autoFillBackground">
- <bool>false</bool>
- </property>
- <property name="text">
- <string>Sign up with a provider</string>
- </property>
- <property name="default">
- <bool>false</bool>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QPushButton" name="loginButton">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="minimumSize">
- <size>
- <width>150</width>
- <height>0</height>
- </size>
- </property>
- <property name="text">
- <string>Log in to your %1</string>
- </property>
- <property name="autoDefault">
- <bool>false</bool>
- </property>
- <property name="default">
- <bool>true</bool>
- </property>
- <property name="flat">
- <bool>false</bool>
- </property>
- </widget>
- </item>
- <item>
- <spacer name="horizontalSpacer_4">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>40</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- </layout>
+ </widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<property name="bottomMargin">
<number>0</number>
</property>
- <item>
- <spacer name="horizontalSpacer_6">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>40</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- <item>
- <widget class="QWidget" name="widget" native="true">
- <layout class="QVBoxLayout" name="verticalLayout_3">
- <item>
- <widget class="QLabel" name="installLink">
- <property name="text">
- <string notr="true">&lt;a href=&quot;https://docs.nextcloud.com/server/latest/admin_manual/installation/#installation&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#7a7a7a;&quot;&gt;Host your own server&lt;/span&gt;&lt;/a&gt;</string>
- </property>
- <property name="openExternalLinks">
- <bool>true</bool>
- </property>
- <property name="textInteractionFlags">
- <set>Qt::LinksAccessibleByKeyboard|Qt::LinksAccessibleByMouse</set>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- </item>
- <item>
- <spacer name="horizontalSpacer_5">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>40</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
</layout>
</item>
- <item>
- <widget class="QLabel" name="bottomLabel">
- <property name="minimumSize">
- <size>
- <width>0</width>
- <height>0</height>
- </size>
- </property>
- <property name="text">
- <string notr="true">TextLabel</string>
- </property>
- <property name="textFormat">
- <enum>Qt::RichText</enum>
- </property>
- </widget>
- </item>
</layout>
</widget>
<customwidgets>
@@ -482,11 +369,6 @@
<extends>QLineEdit</extends>
<header>wizard/postfixlineedit.h</header>
</customwidget>
- <customwidget>
- <class>OCC::SlideShow</class>
- <extends>QWidget</extends>
- <header>wizard/slideshow.h</header>
- </customwidget>
</customwidgets>
<resources/>
<connections/>
diff --git a/src/gui/wizard/owncloudsetuppage.cpp b/src/gui/wizard/owncloudsetuppage.cpp
index eff655e00..800d965d6 100644
--- a/src/gui/wizard/owncloudsetuppage.cpp
+++ b/src/gui/wizard/owncloudsetuppage.cpp
@@ -45,10 +45,9 @@ OwncloudSetupPage::OwncloudSetupPage(QWidget *parent)
{
_ui.setupUi(this);
- Theme *theme = Theme::instance();
- setTitle(WizardCommon::titleTemplate().arg(tr("Connect to %1").arg(theme->appNameGUI())));
- setSubTitle(WizardCommon::subTitleTemplate().arg(tr("Setup %1 server").arg(theme->appNameGUI())));
+ setupServerAddressDescriptionLabel();
+ Theme *theme = Theme::instance();
if (theme->overrideServerUrl().isEmpty()) {
_ui.leUrl->setPostfix(theme->wizardUrlPostfix());
_ui.leUrl->setPlaceholderText(theme->wizardUrlHint());
@@ -59,7 +58,11 @@ OwncloudSetupPage::OwncloudSetupPage(QWidget *parent)
registerField(QLatin1String("OCUrl*"), _ui.leUrl);
- _ui.resultLayout->addWidget(_progressIndi);
+ auto sizePolicy = _progressIndi->sizePolicy();
+ sizePolicy.setRetainSizeWhenHidden(true);
+ _progressIndi->setSizePolicy(sizePolicy);
+
+ _ui.progressLayout->addWidget(_progressIndi);
stopSpinner();
setupCustomization();
@@ -70,35 +73,17 @@ OwncloudSetupPage::OwncloudSetupPage(QWidget *parent)
addCertDial = new AddCertificateDialog(this);
connect(addCertDial, &QDialog::accepted, this, &OwncloudSetupPage::slotCertificateAccepted);
+}
-#ifdef WITH_PROVIDERS
- connect(_ui.loginButton, &QPushButton::clicked, this, &OwncloudSetupPage::slotLogin);
- connect(_ui.createAccountButton, &QPushButton::clicked, this, &OwncloudSetupPage::slotGotoProviderList);
-
- _ui.login->hide();
- _ui.slideShow->addSlide(Theme::hidpiFileName(":/client/theme/colored/wizard-nextcloud.png"), tr("Keep your data secure and under your control"));
- _ui.slideShow->addSlide(Theme::hidpiFileName(":/client/theme/colored/wizard-files.png"), tr("Secure collaboration & file exchange"));
- _ui.slideShow->addSlide(Theme::hidpiFileName(":/client/theme/colored/wizard-groupware.png"), tr("Easy-to-use web mail, calendaring & contacts"));
- _ui.slideShow->addSlide(Theme::hidpiFileName(":/client/theme/colored/wizard-talk.png"), tr("Screensharing, online meetings & web conferences"));
-
- connect(_ui.slideShow, &SlideShow::clicked, _ui.slideShow, &SlideShow::stopShow);
- connect(_ui.nextButton, &QPushButton::clicked, _ui.slideShow, &SlideShow::nextSlide);
- connect(_ui.prevButton, &QPushButton::clicked, _ui.slideShow, &SlideShow::prevSlide);
-
- _ui.slideShow->startShow();
-#else
- _ui.createAccountButton->hide();
- _ui.loginButton->hide();
- _ui.installLink->hide();
- _ui.slideShow->hide();
-#endif
+void OwncloudSetupPage::setLogo()
+{
+ _ui.logoLabel->setPixmap(Theme::instance()->wizardApplicationLogo());
+}
+void OwncloudSetupPage::setupServerAddressDescriptionLabel()
+{
const auto appName = Theme::instance()->appNameGUI();
- _ui.loginButton->setText(tr("Log in to your %1").arg(appName));
- _ui.addressDescriptionLabel->setText(tr("This is the link to your %1 web interface when you open it in the browser.<br/>"
- "It looks like https://cloud.example.com or https://example.com/cloud").arg(appName));
-
- customizeStyle();
+ _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::setServerUrl(const QString &newUrl)
@@ -127,25 +112,17 @@ void OwncloudSetupPage::setupCustomization()
variant = theme->customMedia(Theme::oCSetupBottom);
WizardCommon::setupCustomMedia(variant, _ui.bottomLabel);
+
+ auto leUrlPalette = _ui.leUrl->palette();
+ leUrlPalette.setColor(QPalette::Text, Qt::black);
+ leUrlPalette.setColor(QPalette::Base, Qt::white);
+ _ui.leUrl->setPalette(leUrlPalette);
}
#ifdef WITH_PROVIDERS
void OwncloudSetupPage::slotLogin()
{
- _ui.slideShow->hide();
- _ui.nextButton->hide();
- _ui.prevButton->hide();
-
_ocWizard->setRegistration(false);
- _ui.login->setMaximumHeight(0);
- auto *animation = new QPropertyAnimation(_ui.login, "maximumHeight");
- animation->setDuration(0);
- animation->setStartValue(500);
- animation->setEndValue(500);
- _ui.login->show();
- _ui.loginButton->hide();
- wizard()->resize(wizard()->sizeHint());
- animation->start();
}
void OwncloudSetupPage::slotGotoProviderList()
{
@@ -160,6 +137,14 @@ void OwncloudSetupPage::slotGotoProviderList()
// slot hit from textChanged of the url entry field.
void OwncloudSetupPage::slotUrlChanged(const QString &url)
{
+ // Need to set next button as default button here because
+ // otherwise the on OSX the next button does not stay the default
+ // button
+ auto nextButton = qobject_cast<QPushButton *>(_ocWizard->button(QWizard::NextButton));
+ if (nextButton) {
+ nextButton->setDefault(true);
+ }
+
_authTypeKnown = false;
QString newUrl = url;
@@ -181,16 +166,6 @@ void OwncloudSetupPage::slotUrlChanged(const QString &url)
if (newUrl != url) {
_ui.leUrl->setText(newUrl);
}
-
- const auto isSecure = url.startsWith(QLatin1String("https://"));
- const auto toolTip = isSecure ? tr("This URL is secure. You can use it.")
- : tr("This URL is NOT secure as it is not encrypted.\n"
- "It is not advisable to use it.");
- const auto pixmap = isSecure ? QPixmap(Theme::hidpiFileName(":/client/theme/lock-https.svg"))
- : QPixmap(Theme::hidpiFileName(":/client/theme/lock-http.svg"));
-
- _ui.urlLabel->setToolTip(toolTip);
- _ui.urlLabel->setPixmap(pixmap.scaled(_ui.urlLabel->size(), Qt::KeepAspectRatio));
}
void OwncloudSetupPage::slotUrlEditFinished()
@@ -210,6 +185,8 @@ bool OwncloudSetupPage::isComplete() const
void OwncloudSetupPage::initializePage()
{
+ customizeStyle();
+
WizardCommon::initErrorLabel(_ui.errorLabel);
_authTypeKnown = false;
@@ -217,26 +194,29 @@ void OwncloudSetupPage::initializePage()
QAbstractButton *nextButton = wizard()->button(QWizard::NextButton);
auto *pushButton = qobject_cast<QPushButton *>(nextButton);
- if (pushButton)
+ if (pushButton) {
pushButton->setDefault(true);
+ }
+
+ _ui.leUrl->setFocus();
- // If url is overriden by theme, it's already set and
- // we just check the server type and switch to second page
- // immediately.
- if (Theme::instance()->overrideServerUrl().isEmpty()) {
- _ui.leUrl->setFocus();
- } else if (!Theme::instance()->forceOverrideServerUrl()) {
+ 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
+ // Just focus the next button to let the user navigate quicker
if (nextButton) {
nextButton->setFocus();
}
- } else {
+ } else if (isServerUrlOverridden) {
+ // If the overwritten url is not empty and we force this overwritten url
+ // we just check the server type and switch to next page
+ // immediately.
setCommitPage(true);
// Hack: setCommitPage() changes caption, but after an error this page could still be visible
setButtonText(QWizard::CommitButton, tr("&Next >"));
validatePage();
setVisible(false);
}
- wizard()->resize(wizard()->sizeHint());
}
int OwncloudSetupPage::nextId() const
@@ -269,7 +249,7 @@ bool OwncloudSetupPage::validatePage()
QString u = url();
QUrl qurl(u);
if (!qurl.isValid() || qurl.host().isEmpty()) {
- setErrorString(tr("Invalid URL"), false);
+ setErrorString(tr("Server address does not seem to be valid"), false);
return false;
}
@@ -338,21 +318,18 @@ void OwncloudSetupPage::setErrorString(const QString &err, bool retryHTTPonly)
_checking = false;
emit completeChanged();
stopSpinner();
- wizard()->resize(wizard()->sizeHint());
}
void OwncloudSetupPage::startSpinner()
{
- _ui.resultLayout->setEnabled(true);
- _ui.urlLabel->setVisible(false);
+ _ui.progressLayout->setEnabled(true);
_progressIndi->setVisible(true);
_progressIndi->startAnimation();
}
void OwncloudSetupPage::stopSpinner()
{
- _ui.resultLayout->setEnabled(false);
- _ui.urlLabel->setVisible(true);
+ _ui.progressLayout->setEnabled(false);
_progressIndi->setVisible(false);
_progressIndi->stopAnimation();
}
@@ -397,24 +374,19 @@ void OwncloudSetupPage::slotStyleChanged()
void OwncloudSetupPage::customizeStyle()
{
-#ifdef WITH_PROVIDERS
- Theme *theme = Theme::instance();
-
- bool widgetHasDarkBg = Theme::isDarkColor(QGuiApplication::palette().base().color());
- _ui.nextButton->setIcon(theme->uiThemeIcon(QString("control-next.svg"), widgetHasDarkBg));
- _ui.prevButton->setIcon(theme->uiThemeIcon(QString("control-prev.svg"), widgetHasDarkBg));
-
- // QPushButtons are a mess when it comes to consistent background coloring without stylesheets,
- // so we do it here even though this is an exceptional styling method here
- _ui.createAccountButton->setStyleSheet("QPushButton {background-color: #0082C9; color: white}");
+ setLogo();
+
+ if (_progressIndi) {
+ const auto isDarkBackground = Theme::isDarkColor(palette().window().color());
+ if (isDarkBackground) {
+ _progressIndi->setColor(Qt::white);
+ } else {
+ _progressIndi->setColor(Qt::black);
+ }
+ }
- QPalette pal = _ui.slideShow->palette();
- pal.setColor(QPalette::WindowText, theme->wizardHeaderBackgroundColor());
- _ui.slideShow->setPalette(pal);
-#endif
- if(_progressIndi)
- _progressIndi->setColor(QGuiApplication::palette().color(QPalette::Text));
+ WizardCommon::customizeHintLabel(_ui.serverAddressDescriptionLabel);
}
} // namespace OCC
diff --git a/src/gui/wizard/owncloudsetuppage.h b/src/gui/wizard/owncloudsetuppage.h
index 18b9c0135..485a2bd62 100644
--- a/src/gui/wizard/owncloudsetuppage.h
+++ b/src/gui/wizard/owncloudsetuppage.h
@@ -78,7 +78,9 @@ signals:
void determineAuthType(const QString &);
private:
+ void setLogo();
void customizeStyle();
+ void setupServerAddressDescriptionLabel();
Ui_OwncloudSetupPage _ui;
diff --git a/src/gui/wizard/owncloudwizard.cpp b/src/gui/wizard/owncloudwizard.cpp
index d97b0b19f..4a8e38662 100644
--- a/src/gui/wizard/owncloudwizard.cpp
+++ b/src/gui/wizard/owncloudwizard.cpp
@@ -20,6 +20,7 @@
#include "owncloudgui.h"
#include "wizard/owncloudwizard.h"
+#include "wizard/welcomepage.h"
#include "wizard/owncloudsetuppage.h"
#include "wizard/owncloudhttpcredspage.h"
#include "wizard/owncloudoauthcredspage.h"
@@ -46,17 +47,19 @@ Q_LOGGING_CATEGORY(lcWizard, "nextcloud.gui.wizard", QtInfoMsg)
OwncloudWizard::OwncloudWizard(QWidget *parent)
: QWizard(parent)
, _account(nullptr)
+ , _welcomePage(new WelcomePage(this))
, _setupPage(new OwncloudSetupPage(this))
, _httpCredsPage(new OwncloudHttpCredsPage(this))
, _browserCredsPage(new OwncloudOAuthCredsPage)
, _flow2CredsPage(new Flow2AuthCredsPage)
- , _advancedSetupPage(new OwncloudAdvancedSetupPage)
+ , _advancedSetupPage(new OwncloudAdvancedSetupPage(this))
, _resultPage(new OwncloudWizardResultPage)
, _webViewPage(new WebViewPage(this))
{
setObjectName("owncloudWizard");
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
+ setPage(WizardCommon::Page_Welcome, _welcomePage);
setPage(WizardCommon::Page_ServerSetup, _setupPage);
setPage(WizardCommon::Page_HttpCreds, _httpCredsPage);
setPage(WizardCommon::Page_OAuthCreds, _browserCredsPage);
@@ -69,7 +72,6 @@ OwncloudWizard::OwncloudWizard(QWidget *parent)
// note: start Id is set by the calling class depending on if the
// welcome text is to be shown or not.
- setWizardStyle(QWizard::ModernStyle);
connect(this, &QWizard::currentIdChanged, this, &OwncloudWizard::slotCurrentPageChanged);
connect(_setupPage, &OwncloudSetupPage::determineAuthType, this, &OwncloudWizard::determineAuthType);
@@ -83,17 +85,19 @@ OwncloudWizard::OwncloudWizard(QWidget *parent)
Theme *theme = Theme::instance();
- setWindowTitle(tr("%1 Connection Wizard").arg(theme->appNameGUI()));
+ setWindowTitle(tr("Add %1 account").arg(theme->appNameGUI()));
setWizardStyle(QWizard::ModernStyle);
- setPixmap(QWizard::BannerPixmap, theme->wizardHeaderBanner());
- setPixmap(QWizard::LogoPixmap, theme->wizardHeaderLogo());
setOption(QWizard::NoBackButtonOnStartPage);
setOption(QWizard::NoBackButtonOnLastPage);
setOption(QWizard::NoCancelButton);
- setTitleFormat(Qt::RichText);
- setSubTitleFormat(Qt::RichText);
setButtonText(QWizard::CustomButton1, tr("Skip folders configuration"));
+ // 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
+ // flickering when the page changes
+ auto nextButtonSizePolicy = button(QWizard::NextButton)->sizePolicy();
+ nextButtonSizePolicy.setRetainSizeWhenHidden(true);
+ button(QWizard::NextButton)->setSizePolicy(nextButtonSizePolicy);
// Connect styleChanged events to our widgets, so they can adapt (Dark-/Light-Mode switching)
connect(this, &OwncloudWizard::styleChanged, _setupPage, &OwncloudSetupPage::slotStyleChanged);
@@ -104,6 +108,48 @@ OwncloudWizard::OwncloudWizard(QWidget *parent)
// allow Flow2 page to poll on window activation
connect(this, &OwncloudWizard::onActivate, _flow2CredsPage, &Flow2AuthCredsPage::slotPollNow);
+
+ adjustWizardSize();
+ centerWindow();
+}
+
+void OwncloudWizard::centerWindow()
+{
+ const auto wizardWindow = window();
+ const auto screenGeometry = QGuiApplication::screenAt(wizardWindow->pos())->geometry();
+ const auto windowGeometry = wizardWindow->geometry();
+ const auto newWindowPosition = screenGeometry.center() - QPoint(windowGeometry.width() / 2, windowGeometry.height() / 2);
+ wizardWindow->move(newWindowPosition);
+}
+
+
+void OwncloudWizard::adjustWizardSize()
+{
+ const auto pageSizes = calculateWizardPageSizes();
+ const auto longestSide = calculateLongestSideOfWizardPages(pageSizes);
+
+ resize(QSize(longestSide, longestSide));
+}
+
+QList<QSize> OwncloudWizard::calculateWizardPageSizes() const
+{
+ QList<QSize> pageSizes;
+ const auto pIds = pageIds();
+
+ std::transform(pIds.cbegin(), pIds.cend(), std::back_inserter(pageSizes), [this](int pageId) {
+ auto p = page(pageId);
+ p->adjustSize();
+ return p->sizeHint();
+ });
+
+ return pageSizes;
+}
+
+int OwncloudWizard::calculateLongestSideOfWizardPages(const QList<QSize> &pageSizes) const
+{
+ return std::accumulate(std::cbegin(pageSizes), std::cend(pageSizes), 0, [](int current, const QSize &size) {
+ return std::max({ current, size.width(), size.height() });
+ });
}
void OwncloudWizard::setAccount(AccountPtr account)
@@ -220,6 +266,28 @@ void OwncloudWizard::slotCurrentPageChanged(int id)
{
qCDebug(lcWizard) << "Current Wizard page changed to " << id;
+ const auto setNextButtonAsDefault = [this]() {
+ auto nextButton = qobject_cast<QPushButton *>(button(QWizard::NextButton));
+ if (nextButton) {
+ nextButton->setDefault(true);
+ }
+ };
+
+ if (id == WizardCommon::Page_Welcome) {
+ // Set next button to just hidden so it retains it's layout
+ button(QWizard::NextButton)->setHidden(true);
+ // Need to set it from here, otherwise it has no effect
+ _welcomePage->setLoginButtonDefault();
+ } else if (id == WizardCommon::Page_WebView || id == WizardCommon::Page_Flow2AuthCreds) {
+ setButtonLayout({ QWizard::Stretch, QWizard::BackButton });
+ } else if (id == WizardCommon::Page_AdvancedSetup) {
+ setButtonLayout({ QWizard::Stretch, QWizard::CustomButton1, QWizard::BackButton, QWizard::NextButton });
+ setNextButtonAsDefault();
+ } else {
+ setButtonLayout({ QWizard::Stretch, QWizard::BackButton, QWizard::NextButton });
+ setNextButtonAsDefault();
+ }
+
if (id == WizardCommon::Page_ServerSetup) {
emit clearPendingRequests();
}
@@ -232,7 +300,6 @@ void OwncloudWizard::slotCurrentPageChanged(int id)
done(Accepted);
}
- setOption(QWizard::HaveCustomButton1, id == WizardCommon::Page_AdvancedSetup);
if (id == WizardCommon::Page_AdvancedSetup && (_credentialsPage == _browserCredsPage || _credentialsPage == _flow2CredsPage)) {
// For OAuth, disable the back button in the Page_AdvancedSetup because we don't want
// to re-open the browser.
@@ -302,6 +369,15 @@ void OwncloudWizard::changeEvent(QEvent *e)
void OwncloudWizard::customizeStyle()
{
// HINT: Customize wizard's own style here, if necessary in the future (Dark-/Light-Mode switching)
+
+ // Set background colors
+ auto wizardPalette = palette();
+ const auto backgroundColor = wizardPalette.color(QPalette::Window);
+ wizardPalette.setColor(QPalette::Base, backgroundColor);
+ // Set separator color
+ wizardPalette.setColor(QPalette::Mid, backgroundColor);
+
+ setPalette(wizardPalette);
}
void OwncloudWizard::bringToTop()
diff --git a/src/gui/wizard/owncloudwizard.h b/src/gui/wizard/owncloudwizard.h
index 947d5f679..e8480d3bd 100644
--- a/src/gui/wizard/owncloudwizard.h
+++ b/src/gui/wizard/owncloudwizard.h
@@ -29,6 +29,7 @@ namespace OCC {
Q_DECLARE_LOGGING_CATEGORY(lcWizard)
+class WelcomePage;
class OwncloudSetupPage;
class OwncloudHttpCredsPage;
class OwncloudOAuthCredsPage;
@@ -73,6 +74,7 @@ public:
AbstractCredentials *getCredentials() const;
void bringToTop();
+ void centerWindow();
/**
* Shows a dialog explaining the virtual files mode and warning about it
@@ -113,8 +115,12 @@ protected:
private:
void customizeStyle();
+ void adjustWizardSize();
+ int calculateLongestSideOfWizardPages(const QList<QSize> &pageSizes) const;
+ QList<QSize> calculateWizardPageSizes() const;
AccountPtr _account;
+ WelcomePage *_welcomePage;
OwncloudSetupPage *_setupPage;
OwncloudHttpCredsPage *_httpCredsPage;
OwncloudOAuthCredsPage *_browserCredsPage;
diff --git a/src/gui/wizard/owncloudwizardcommon.cpp b/src/gui/wizard/owncloudwizardcommon.cpp
index 56768209b..0f4735082 100644
--- a/src/gui/wizard/owncloudwizardcommon.cpp
+++ b/src/gui/wizard/owncloudwizardcommon.cpp
@@ -16,6 +16,10 @@
#include <QLabel>
#include <QPixmap>
#include <QVariant>
+#include <QRadioButton>
+#include <QAbstractButton>
+#include <QCheckBox>
+#include <QSpinBox>
#include "wizard/owncloudwizardcommon.h"
#include "theme.h"
@@ -68,6 +72,15 @@ namespace WizardCommon {
errorLabel->setVisible(false);
}
+ void customizeHintLabel(QLabel *label)
+ {
+ auto palette = label->palette();
+ QColor textColor = palette.color(QPalette::Text);
+ textColor.setAlpha(128);
+ palette.setColor(QPalette::Text, textColor);
+ label->setPalette(palette);
+ }
+
} // ns WizardCommon
} // namespace OCC
diff --git a/src/gui/wizard/owncloudwizardcommon.h b/src/gui/wizard/owncloudwizardcommon.h
index d1f7c08be..5ebcca01f 100644
--- a/src/gui/wizard/owncloudwizardcommon.h
+++ b/src/gui/wizard/owncloudwizardcommon.h
@@ -16,8 +16,14 @@
#ifndef MIRALL_OWNCLOUD_WIZARD_COMMON_H
#define MIRALL_OWNCLOUD_WIZARD_COMMON_H
+#include <QString>
+
class QVariant;
class QLabel;
+class QRadioButton;
+class QSpinBox;
+class QCheckBox;
+class QAbstractButton;
namespace OCC {
@@ -27,6 +33,7 @@ namespace WizardCommon {
QString titleTemplate();
QString subTitleTemplate();
void initErrorLabel(QLabel *errorLabel);
+ void customizeHintLabel(QLabel *label);
enum SyncMode {
SelectiveMode,
@@ -34,6 +41,7 @@ namespace WizardCommon {
};
enum Pages {
+ Page_Welcome,
Page_ServerSetup,
Page_HttpCreds,
Page_ShibbolethCreds,
diff --git a/src/gui/wizard/webview.ui b/src/gui/wizard/webview.ui
index ba3588ca8..8ab0665b7 100644
--- a/src/gui/wizard/webview.ui
+++ b/src/gui/wizard/webview.ui
@@ -11,15 +11,15 @@
</rect>
</property>
<property name="sizePolicy">
- <sizepolicy hsizetype="Minimum" vsizetype="MinimumExpanding">
+ <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
- <width>800</width>
- <height>650</height>
+ <width>0</width>
+ <height>0</height>
</size>
</property>
<property name="windowTitle">
diff --git a/src/gui/wizard/webviewpage.cpp b/src/gui/wizard/webviewpage.cpp
index 01311e839..7aae73fc8 100644
--- a/src/gui/wizard/webviewpage.cpp
+++ b/src/gui/wizard/webviewpage.cpp
@@ -4,6 +4,7 @@
#include <QProgressBar>
#include <QVBoxLayout>
#include <QNetworkProxyFactory>
+#include <QScreen>
#include "owncloudwizard.h"
#include "creds/webflowcredentials.h"
@@ -24,6 +25,7 @@ WebViewPage::WebViewPage(QWidget *parent)
_webView = new WebView(this);
auto *layout = new QVBoxLayout(this);
+ layout->setMargin(0);
layout->addWidget(_webView);
setLayout(layout);
@@ -52,6 +54,44 @@ void WebViewPage::initializePage() {
}
qCInfo(lcWizardWebiewPage()) << "Url to auth at: " << url;
_webView->setUrl(QUrl(url));
+
+ _originalWizardSize = _ocWizard->size();
+ resizeWizard();
+}
+
+void WebViewPage::resizeWizard()
+{
+ // The webview needs a little bit more space
+ auto wizardSizeChanged = tryToSetWizardSize(_originalWizardSize.width() * 2, _originalWizardSize.height() * 2);
+
+ if (!wizardSizeChanged) {
+ wizardSizeChanged = tryToSetWizardSize(static_cast<int>(_originalWizardSize.width() * 1.5), static_cast<int>(_originalWizardSize.height() * 1.5));
+ }
+
+ if (wizardSizeChanged) {
+ _ocWizard->centerWindow();
+ }
+}
+
+bool WebViewPage::tryToSetWizardSize(int width, int height)
+{
+ const auto window = _ocWizard->window();
+ const auto screenGeometry = QGuiApplication::screenAt(window->pos())->geometry();
+ const auto windowWidth = screenGeometry.width();
+ const auto windowHeight = screenGeometry.height();
+
+ if (width < windowWidth && height < windowHeight) {
+ _ocWizard->resize(width, height);
+ return true;
+ }
+
+ return false;
+}
+
+void WebViewPage::cleanupPage()
+{
+ _ocWizard->resize(_originalWizardSize);
+ _ocWizard->centerWindow();
}
int WebViewPage::nextId() const {
diff --git a/src/gui/wizard/webviewpage.h b/src/gui/wizard/webviewpage.h
index 65f00c33b..c621e99f1 100644
--- a/src/gui/wizard/webviewpage.h
+++ b/src/gui/wizard/webviewpage.h
@@ -17,6 +17,7 @@ public:
~WebViewPage();
void initializePage() override;
+ void cleanupPage() override;
int nextId() const override;
bool isComplete() const override;
@@ -30,6 +31,9 @@ private slots:
void urlCatched(QString user, QString pass, QString host);
private:
+ void resizeWizard();
+ bool tryToSetWizardSize(int width, int height);
+
OwncloudWizard *_ocWizard;
WebView *_webView;
@@ -37,6 +41,8 @@ private:
QString _pass;
bool _useSystemProxy;
+
+ QSize _originalWizardSize;
};
}
diff --git a/src/gui/wizard/welcomepage.cpp b/src/gui/wizard/welcomepage.cpp
new file mode 100644
index 000000000..668c5b02f
--- /dev/null
+++ b/src/gui/wizard/welcomepage.cpp
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2021 by Felix Weilbach <felix.weilbach@nextcloud.com>
+ *
+ * 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 "welcomepage.h"
+#include "theme.h"
+#include "wizard/owncloudwizard.h"
+#include "wizard/slideshow.h"
+#include "ui_welcomepage.h"
+
+namespace OCC {
+
+WelcomePage::WelcomePage(OwncloudWizard *ocWizard)
+ : QWizardPage()
+ , _ui(new Ui::WelcomePage)
+ , _ocWizard(ocWizard)
+{
+ setupUi();
+}
+
+WelcomePage::~WelcomePage() = default;
+
+void WelcomePage::setupUi()
+{
+ _ui->setupUi(this);
+ setupSlideShow();
+ setupLoginButton();
+ setupCreateAccountButton();
+ setupHostYourOwnServerLabel();
+}
+
+void WelcomePage::initializePage()
+{
+ customizeStyle();
+}
+
+void WelcomePage::setLoginButtonDefault()
+{
+ _ui->loginButton->setDefault(true);
+ _ui->loginButton->setFocus();
+}
+
+void WelcomePage::styleSlideShow()
+{
+ const auto theme = Theme::instance();
+ const auto backgroundColor = palette().window().color();
+
+ const auto wizardNextcloudIconFileName = theme->isBranded() ? Theme::hidpiFileName("wizard-nextcloud.png", backgroundColor)
+ : Theme::hidpiFileName(":/client/theme/colored/wizard-nextcloud.png");
+ const auto wizardFilesIconFileName = theme->isBranded() ? Theme::hidpiFileName("wizard-files.png", backgroundColor)
+ : Theme::hidpiFileName(":/client/theme/colored/wizard-files.png");
+ const auto wizardGroupwareIconFileName = theme->isBranded() ? Theme::hidpiFileName("wizard-groupware.png", backgroundColor)
+ : Theme::hidpiFileName(":/client/theme/colored/wizard-groupware.png");
+ const auto wizardTalkIconFileName = theme->isBranded() ? Theme::hidpiFileName("wizard-talk.png", backgroundColor)
+ : Theme::hidpiFileName(":/client/theme/colored/wizard-talk.png");
+
+ _ui->slideShow->addSlide(wizardNextcloudIconFileName, tr("Keep your data secure and under your control"));
+ _ui->slideShow->addSlide(wizardFilesIconFileName, tr("Secure collaboration & file exchange"));
+ _ui->slideShow->addSlide(wizardGroupwareIconFileName, tr("Easy-to-use web mail, calendaring & contacts"));
+ _ui->slideShow->addSlide(wizardTalkIconFileName, tr("Screensharing, online meetings & web conferences"));
+
+ const auto isDarkBackground = Theme::isDarkColor(backgroundColor);
+ _ui->slideShowNextButton->setIcon(theme->uiThemeIcon(QString("control-next.svg"), isDarkBackground));
+ _ui->slideShowPreviousButton->setIcon(theme->uiThemeIcon(QString("control-prev.svg"), isDarkBackground));
+}
+
+void WelcomePage::setupSlideShow()
+{
+ connect(_ui->slideShow, &SlideShow::clicked, _ui->slideShow, &SlideShow::stopShow);
+ connect(_ui->slideShowNextButton, &QPushButton::clicked, _ui->slideShow, &SlideShow::nextSlide);
+ connect(_ui->slideShowPreviousButton, &QPushButton::clicked, _ui->slideShow, &SlideShow::prevSlide);
+}
+
+void WelcomePage::setupLoginButton()
+{
+ const auto appName = Theme::instance()->appNameGUI();
+
+ _ui->loginButton->setText(tr("Log in to your %1").arg(appName));
+ connect(_ui->loginButton, &QPushButton::clicked, this, [this](bool /*checked*/) {
+ _nextPage = WizardCommon::Page_ServerSetup;
+ _ocWizard->next();
+ });
+}
+
+void WelcomePage::setupCreateAccountButton()
+{
+ connect(_ui->createAccountButton, &QPushButton::clicked, this, [this](bool /*checked*/) {
+ _ocWizard->setRegistration(true);
+ _nextPage = WizardCommon::Page_WebView;
+ _ocWizard->next();
+ });
+}
+
+void WelcomePage::setupHostYourOwnServerLabel()
+{
+ _ui->hostYourOwnServerLabel->setText(tr("Host your own server"));
+ _ui->hostYourOwnServerLabel->setAlignment(Qt::AlignCenter);
+ _ui->hostYourOwnServerLabel->setUrl(QUrl("https://docs.nextcloud.com/server/latest/admin_manual/installation/#installation"));
+}
+
+int WelcomePage::nextId() const
+{
+ return _nextPage;
+}
+
+void WelcomePage::customizeStyle()
+{
+ styleSlideShow();
+}
+}
diff --git a/src/gui/wizard/welcomepage.h b/src/gui/wizard/welcomepage.h
new file mode 100644
index 000000000..9d0aa1c0a
--- /dev/null
+++ b/src/gui/wizard/welcomepage.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2021 by Felix Weilbach <felix.weilbach@nextcloud.com>
+ *
+ * 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 <QWizardPage>
+
+#include "wizard/owncloudwizardcommon.h"
+
+namespace OCC {
+
+class OwncloudWizard;
+
+namespace Ui {
+ class WelcomePage;
+}
+
+class WelcomePage : public QWizardPage
+{
+ Q_OBJECT
+
+public:
+ explicit WelcomePage(OwncloudWizard *ocWizard);
+ ~WelcomePage() override;
+ int nextId() const override;
+ void initializePage() override;
+ void setLoginButtonDefault();
+
+private:
+ void setupUi();
+ void customizeStyle();
+ void styleSlideShow();
+ void setupSlideShow();
+ void setupLoginButton();
+ void setupCreateAccountButton();
+ void setupHostYourOwnServerLabel();
+
+ QScopedPointer<Ui::WelcomePage> _ui;
+
+ OwncloudWizard *_ocWizard;
+ WizardCommon::Pages _nextPage = WizardCommon::Page_ServerSetup;
+};
+}
diff --git a/src/gui/wizard/welcomepage.ui b/src/gui/wizard/welcomepage.ui
new file mode 100644
index 000000000..1d54a8027
--- /dev/null
+++ b/src/gui/wizard/welcomepage.ui
@@ -0,0 +1,229 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>OCC::WelcomePage</class>
+ <widget class="QWidget" name="OCC::WelcomePage">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>500</width>
+ <height>500</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="windowTitle">
+ <string>Form</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_2">
+ <item>
+ <spacer name="verticalSpacer_3">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Expanding</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>80</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_2">
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QPushButton" name="slideShowPreviousButton">
+ <property name="maximumSize">
+ <size>
+ <width>40</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="autoDefault">
+ <bool>false</bool>
+ </property>
+ <property name="default">
+ <bool>false</bool>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="OCC::SlideShow" name="slideShow" native="true">
+ <property name="font">
+ <font>
+ <pointsize>12</pointsize>
+ <weight>75</weight>
+ <bold>true</bold>
+ </font>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="slideShowNextButton">
+ <property name="maximumSize">
+ <size>
+ <width>40</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="autoDefault">
+ <bool>false</bool>
+ </property>
+ <property name="default">
+ <bool>false</bool>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <spacer name="verticalSpacer">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="loginButton">
+ <property name="text">
+ <string>Log in to your %1</string>
+ </property>
+ <property name="autoDefault">
+ <bool>true</bool>
+ </property>
+ <property name="default">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="createAccountButton">
+ <property name="text">
+ <string>Create account with Provider</string>
+ </property>
+ <property name="autoDefault">
+ <bool>true</bool>
+ </property>
+ <property name="default">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="OCC::LinkLabel" name="hostYourOwnServerLabel" native="true"/>
+ </item>
+ <item>
+ <spacer name="verticalSpacer_5">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_2">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <spacer name="verticalSpacer_4">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>OCC::SlideShow</class>
+ <extends>QWidget</extends>
+ <header>wizard/slideshow.h</header>
+ </customwidget>
+ <customwidget>
+ <class>OCC::LinkLabel</class>
+ <extends>QWidget</extends>
+ <header>wizard/linklabel.h</header>
+ <container>1</container>
+ </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src/libsync/nextcloudtheme.cpp b/src/libsync/nextcloudtheme.cpp
index 0ec3f2d27..2a709564c 100644
--- a/src/libsync/nextcloudtheme.cpp
+++ b/src/libsync/nextcloudtheme.cpp
@@ -35,7 +35,7 @@ NextcloudTheme::NextcloudTheme()
QString NextcloudTheme::wizardUrlHint() const
{
- return QString("https://host:port");
+ return QString("https://try.nextcloud.com");
}
}
diff --git a/src/libsync/theme.cpp b/src/libsync/theme.cpp
index be3bde5e6..b77a66655 100644
--- a/src/libsync/theme.cpp
+++ b/src/libsync/theme.cpp
@@ -246,6 +246,12 @@ QString Theme::themeImagePath(const QString &name, int size, bool sysTray) const
}
}
+bool Theme::isHidpi(QPaintDevice *dev)
+{
+ const auto devicePixelRatio = dev ? dev->devicePixelRatio() : qApp->primaryScreen()->devicePixelRatio();
+ return devicePixelRatio > 1;
+}
+
QIcon Theme::uiThemeIcon(const QString &iconName, bool uiHasDarkBg) const
{
QString themeResBasePath = ":/client/theme/";
@@ -256,8 +262,7 @@ QIcon Theme::uiThemeIcon(const QString &iconName, bool uiHasDarkBg) const
QString Theme::hidpiFileName(const QString &fileName, QPaintDevice *dev)
{
- qreal devicePixelRatio = dev ? dev->devicePixelRatio() : qApp->primaryScreen()->devicePixelRatio();
- if (devicePixelRatio <= 1.0) {
+ if (!Theme::isHidpi(dev)) {
return fileName;
}
// try to find a 2x version
@@ -274,6 +279,16 @@ QString Theme::hidpiFileName(const QString &fileName, QPaintDevice *dev)
return fileName;
}
+QString Theme::hidpiFileName(const QString &iconName, const QColor &backgroundColor, QPaintDevice *dev)
+{
+ const auto isDarkBackground = Theme::isDarkColor(backgroundColor);
+
+ const QString themeResBasePath = ":/client/theme/";
+ const QString iconPath = themeResBasePath + (isDarkBackground ? "white/" : "black/") + iconName;
+
+ return Theme::hidpiFileName(iconPath, dev);
+}
+
#endif
@@ -541,6 +556,29 @@ QColor Theme::wizardHeaderBackgroundColor() const
return {APPLICATION_WIZARD_HEADER_BACKGROUND_COLOR};
}
+QPixmap Theme::wizardApplicationLogo() const
+{
+ if (!Theme::isBranded()) {
+ return QPixmap(Theme::hidpiFileName(":/client/theme/colored/wizard-nextcloud.png"));
+ }
+#ifdef APPLICATION_WIZARD_USE_CUSTOM_LOGO
+ const auto useSvg = shouldPreferSvg();
+ const auto logoBasePath = QStringLiteral(":/client/theme/colored/wizard_logo");
+ if (useSvg) {
+ const auto maxHeight = Theme::isHidpi() ? 200 : 100;
+ const auto maxWidth = 2 * maxHeight;
+ const auto icon = QIcon(logoBasePath + ".svg");
+ const auto size = icon.actualSize(QSize(maxWidth, maxHeight));
+ return icon.pixmap(size);
+ } else {
+ return QPixmap(hidpiFileName(logoBasePath + ".png"));
+ }
+#else
+ const auto size = Theme::isHidpi() ?: 200 : 100;
+ return applicationIcon().pixmap(size);
+#endif
+}
+
QPixmap Theme::wizardHeaderLogo() const
{
#ifdef APPLICATION_WIZARD_USE_CUSTOM_LOGO
diff --git a/src/libsync/theme.h b/src/libsync/theme.h
index 394cb8930..a06828b1f 100644
--- a/src/libsync/theme.h
+++ b/src/libsync/theme.h
@@ -132,6 +132,10 @@ public:
#ifndef TOKEN_AUTH_ONLY
static QString hidpiFileName(const QString &fileName, QPaintDevice *dev = nullptr);
+ static QString hidpiFileName(const QString &iconName, const QColor &backgroundColor, QPaintDevice *dev = nullptr);
+
+ static bool isHidpi(QPaintDevice *dev = nullptr);
+
/**
* get an sync state icon
*/
@@ -231,6 +235,8 @@ public:
/** @return color for the setup wizard. */
virtual QColor wizardHeaderBackgroundColor() const;
+ virtual QPixmap wizardApplicationLogo() const;
+
/** @return logo for the setup wizard. */
virtual QPixmap wizardHeaderLogo() const;
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 2297eb0da..9dcc1730d 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -9,6 +9,7 @@ add_library(testutils
STATIC
syncenginetestutils.cpp
pushnotificationstestutils.cpp
+ themeutils.cpp
)
target_link_libraries(testutils PUBLIC ${APPLICATION_EXECUTABLE}sync Qt5::Test)
@@ -54,6 +55,7 @@ nextcloud_add_test(LockedFiles)
nextcloud_add_test(FolderWatcher)
nextcloud_add_test(Capabilities)
nextcloud_add_test(PushNotifications)
+nextcloud_add_test(Theme)
if( UNIX AND NOT APPLE )
nextcloud_add_test(InotifyWatcher)
diff --git a/test/testtheme.cpp b/test/testtheme.cpp
new file mode 100644
index 000000000..52bc7b324
--- /dev/null
+++ b/test/testtheme.cpp
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2021 by Felix Weilbach <felix.weilbach@nextcloud.com>
+ *
+ * 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 <QTest>
+
+#include "theme.h"
+#include "themeutils.h"
+
+class TestTheme : public QObject
+{
+ Q_OBJECT
+
+public:
+ TestTheme()
+ {
+ Q_INIT_RESOURCE(resources);
+ Q_INIT_RESOURCE(theme);
+ }
+
+private slots:
+ void testHidpiFileName_darkBackground_returnPathToWhiteIcon()
+ {
+ FakePaintDevice paintDevice;
+ const QColor backgroundColor("#000000");
+ const QString iconName("icon-name");
+
+ const auto iconPath = OCC::Theme::hidpiFileName(iconName + ".png", backgroundColor, &paintDevice);
+
+ QCOMPARE(iconPath, ":/client/theme/white/" + iconName + ".png");
+ }
+
+ void testHidpiFileName_lightBackground_returnPathToBlackIcon()
+ {
+ FakePaintDevice paintDevice;
+ const QColor backgroundColor("#ffffff");
+ const QString iconName("icon-name");
+
+ const auto iconPath = OCC::Theme::hidpiFileName(iconName + ".png", backgroundColor, &paintDevice);
+
+ QCOMPARE(iconPath, ":/client/theme/black/" + iconName + ".png");
+ }
+
+ void testHidpiFileName_hidpiDevice_returnHidpiIconPath()
+ {
+ FakePaintDevice paintDevice;
+ paintDevice.setHidpi(true);
+ const QColor backgroundColor("#000000");
+ const QString iconName("wizard-files");
+
+ const auto iconPath = OCC::Theme::hidpiFileName(iconName + ".png", backgroundColor, &paintDevice);
+
+ QCOMPARE(iconPath, ":/client/theme/white/" + iconName + "@2x.png");
+ }
+
+ void testIsDarkColor_nextcloudBlue_returnTrue()
+ {
+ const QColor color(0, 130, 201);
+
+ const auto result = OCC::Theme::isDarkColor(color);
+
+ QCOMPARE(result, true);
+ }
+
+ void testIsDarkColor_lightColor_returnFalse()
+ {
+ const QColor color(255, 255, 255);
+
+ const auto result = OCC::Theme::isDarkColor(color);
+
+ QCOMPARE(result, false);
+ }
+
+ void testIsDarkColor_darkColor_returnTrue()
+ {
+ const QColor color(0, 0, 0);
+
+ const auto result = OCC::Theme::isDarkColor(color);
+
+ QCOMPARE(result, true);
+ }
+
+ void testIsHidpi_hidpi_returnTrue()
+ {
+ FakePaintDevice paintDevice;
+ paintDevice.setHidpi(true);
+
+ QCOMPARE(OCC::Theme::isHidpi(&paintDevice), true);
+ }
+
+ void testIsHidpi_lowdpi_returnFalse()
+ {
+ FakePaintDevice paintDevice;
+ paintDevice.setHidpi(false);
+
+ QCOMPARE(OCC::Theme::isHidpi(&paintDevice), false);
+ }
+};
+
+QTEST_GUILESS_MAIN(TestTheme)
+#include "testtheme.moc"
diff --git a/test/themeutils.cpp b/test/themeutils.cpp
new file mode 100644
index 000000000..763d58a1f
--- /dev/null
+++ b/test/themeutils.cpp
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2021 by Felix Weilbach <felix.weilbach@nextcloud.com>
+ *
+ * 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 "themeutils.h"
+
+FakePaintDevice::FakePaintDevice() = default;
+
+QPaintEngine *FakePaintDevice::paintEngine() const
+{
+ return nullptr;
+}
+
+void FakePaintDevice::setHidpi(bool value)
+{
+ _hidpi = value;
+}
+
+int FakePaintDevice::metric(QPaintDevice::PaintDeviceMetric metric) const
+{
+ switch (metric) {
+ case QPaintDevice::PdmDevicePixelRatio:
+ if (_hidpi) {
+ return 2;
+ }
+ return 1;
+ default:
+ return QPaintDevice::metric(metric);
+ }
+}
diff --git a/test/themeutils.h b/test/themeutils.h
new file mode 100644
index 000000000..4e8327e54
--- /dev/null
+++ b/test/themeutils.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) by Felix Weilbach <felix.weilbach@nextcloud.com>
+ *
+ * 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 <QPaintDevice>
+#include <QTest>
+
+class FakePaintDevice : public QPaintDevice
+{
+public:
+ FakePaintDevice();
+
+ QPaintEngine *paintEngine() const override;
+
+ void setHidpi(bool value);
+
+protected:
+ int metric(QPaintDevice::PaintDeviceMetric metric) const override;
+
+private:
+ bool _hidpi = false;
+};
diff --git a/theme.qrc b/theme.qrc
index 7d0c732b8..620a40602 100644
--- a/theme.qrc
+++ b/theme.qrc
@@ -80,6 +80,12 @@
<file>theme/colored/state-warning-64.png</file>
<file>theme/colored/state-warning-128.png</file>
<file>theme/colored/state-warning-256.png</file>
+ <file>theme/black/folder.png</file>
+ <file>theme/black/folder@2x.png</file>
+ <file>theme/white/folder.png</file>
+ <file>theme/white/folder@2x.png</file>
+ <file>theme/colored/folder.png</file>
+ <file>theme/colored/folder@2x.png</file>
<file>theme/black/control-next.svg</file>
<file>theme/black/control-prev.svg</file>
<file>theme/black/state-error.svg</file>
@@ -124,6 +130,23 @@
<file>theme/white/state-warning-64.png</file>
<file>theme/white/state-warning-128.png</file>
<file>theme/white/state-warning-256.png</file>
+ <file>theme/white/wizard-files.png</file>
+ <file>theme/white/wizard-files@2x.png</file>
+ <file>theme/white/wizard-groupware.png</file>
+ <file>theme/white/wizard-groupware@2x.png</file>
+ <file>theme/white/wizard-nextcloud.png</file>
+ <file>theme/white/wizard-nextcloud@2x.png</file>
+ <file>theme/white/wizard-talk.png</file>
+ <file>theme/white/wizard-talk@2x.png</file>
+ <file>theme/black/wizard-files.png</file>
+ <file>theme/black/wizard-files@2x.png</file>
+ <file>theme/black/wizard-groupware.png</file>
+ <file>theme/black/wizard-groupware@2x.png</file>
+ <file>theme/black/wizard-nextcloud.png</file>
+ <file>theme/black/wizard-nextcloud@2x.png</file>
+ <file>theme/black/wizard-talk.png</file>
+ <file>theme/black/wizard-talk@2x.png</file>
+ <file>theme/black/wizard-files.png</file>
<file>theme/colored/wizard-files.png</file>
<file>theme/colored/wizard-files@2x.png</file>
<file>theme/colored/wizard-groupware.png</file>
@@ -132,6 +155,13 @@
<file>theme/colored/wizard-nextcloud@2x.png</file>
<file>theme/colored/wizard-talk.png</file>
<file>theme/colored/wizard-talk@2x.png</file>
+ <file>theme/sync-arrow.svg</file>
+ <file>theme/white/external.png</file>
+ <file>theme/white/external@2x.png</file>
+ <file>theme/black/external.png</file>
+ <file>theme/black/external@2x.png</file>
+ <file>theme/colored/external.png</file>
+ <file>theme/colored/external@2x.png</file>
<file>theme/white/folder.svg</file>
<file>theme/white/more-apps.svg</file>
<file>theme/white/talk-app.svg</file>
diff --git a/theme/black/external.png b/theme/black/external.png
new file mode 100644
index 000000000..db82098ec
--- /dev/null
+++ b/theme/black/external.png
Binary files differ
diff --git a/theme/black/external.svg b/theme/black/external.svg
new file mode 100644
index 000000000..79c9cebf5
--- /dev/null
+++ b/theme/black/external.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><path d="M3.2 2C2.53 2 2 2.54 2 3.2v9.6c0 .67.53 1.2 1.2 1.2h9.6c.67 0 1.2-.53 1.2-1.2V8.98l-1.2-1.2v5.02H3.2V3.2h5.02L7.08 2.06 7.02 2H3.2z"/><path d="M8.14 1l2.29 2.29L7 6.7 9.29 9l3.42-3.43L15 7.86V1z"/></svg> \ No newline at end of file
diff --git a/theme/black/external@2x.png b/theme/black/external@2x.png
new file mode 100644
index 000000000..04779d859
--- /dev/null
+++ b/theme/black/external@2x.png
Binary files differ
diff --git a/theme/black/folder.png b/theme/black/folder.png
new file mode 100644
index 000000000..3d67f6ec2
--- /dev/null
+++ b/theme/black/folder.png
Binary files differ
diff --git a/theme/black/folder.svg b/theme/black/folder.svg
new file mode 100644
index 000000000..9289fb05d
--- /dev/null
+++ b/theme/black/folder.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" height="32" viewBox="0 0 32 32" width="32" version="1.1"><path fill="#000000" d="m3 4c-0.5 0-1 0.5-1 1v22c0 0.52 0.48 1 1 1h26c0.52 0 1-0.482 1-1v-18c0-0.5-0.5-1-1-1h-13l-4-4z"/></svg>
diff --git a/theme/black/folder@2x.png b/theme/black/folder@2x.png
new file mode 100644
index 000000000..2ac972b9a
--- /dev/null
+++ b/theme/black/folder@2x.png
Binary files differ
diff --git a/theme/black/wizard-files.png b/theme/black/wizard-files.png
new file mode 100644
index 000000000..01c6a2540
--- /dev/null
+++ b/theme/black/wizard-files.png
Binary files differ
diff --git a/theme/black/wizard-files.svg b/theme/black/wizard-files.svg
new file mode 100644
index 000000000..6c3ff3761
--- /dev/null
+++ b/theme/black/wizard-files.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" height="16" viewBox="0 0 16 16" width="16" version="1.1"><path fill="#000000" d="m1.5 2c-0.25 0-0.5 0.25-0.5 0.5v11c0 0.26 0.24 0.5 0.5 0.5h13c0.26 0 0.5-0.241 0.5-0.5v-9c0-0.25-0.25-0.5-0.5-0.5h-6.5l-2-2h-4.5zm8.75 3.5a1.25 1.25 0 0 1 1.25 1.25 1.25 1.25 0 0 1 -1.25 1.25 1.25 1.25 0 0 1 -0.8008 -0.291l-2.4512 1.2265a1.25 1.25 0 0 1 0.002 0.0645 1.25 1.25 0 0 1 -0.0039 0.0645l2.4531 1.2265a1.25 1.25 0 0 1 0.8008 -0.291 1.25 1.25 0 0 1 1.25 1.25 1.25 1.25 0 0 1 -1.25 1.25 1.25 1.25 0 0 1 -1.25 -1.25 1.25 1.25 0 0 1 0.0039 -0.064l-2.4531-1.227a1.25 1.25 0 0 1 -0.8008 0.291 1.25 1.25 0 0 1 -1.25 -1.25 1.25 1.25 0 0 1 1.25 -1.25 1.25 1.25 0 0 1 0.8008 0.291l2.4512-1.2265a1.25 1.25 0 0 1 -0.002 -0.0645 1.25 1.25 0 0 1 1.25 -1.25z"/></svg>
diff --git a/theme/black/wizard-files@2x.png b/theme/black/wizard-files@2x.png
new file mode 100644
index 000000000..30a6ddfaf
--- /dev/null
+++ b/theme/black/wizard-files@2x.png
Binary files differ
diff --git a/theme/black/wizard-groupware.png b/theme/black/wizard-groupware.png
new file mode 100644
index 000000000..f560466a2
--- /dev/null
+++ b/theme/black/wizard-groupware.png
Binary files differ
diff --git a/theme/black/wizard-groupware.svg b/theme/black/wizard-groupware.svg
new file mode 100644
index 000000000..f7f31340b
--- /dev/null
+++ b/theme/black/wizard-groupware.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 16 16" height="16" width="16" version="1.1"><path fill="#000000" d="m9 1c-1.746 0-3 1.43-3 2.8 0 1.4 0.1 2.4 0.8 3.5 0.224 0.29 0.485 0.35 0.7 0.6 0.135 0.5 0.24 1 0.1 1.5-0.436 0.153-0.85 0.332-1.27 0.5-0.51-0.273-1.1-0.5-1.61-0.7-0.07-0.28-0.02-0.487 0.05-0.75 0.12-0.125 0.23-0.18 0.36-0.3 0.37-0.45 0.39-1.21 0.39-1.75 0-0.8-0.72-1.4-1.5-1.4-0.87 0-1.5 0.72-1.5 1.4h-0.02c0 0.7 0.05 1.2 0.4 1.75 0.1 0.15 0.242 0.175 0.35 0.3 0.0674 0.25 0.121 0.5 0.05 0.75-0.64 0.223-1.244 0.5-1.8 0.8-0.42 0.3-0.233 0.182-0.5 1.15-0.124 0.5 1.3 0.73 2.32 0.81-0.05 0.275-0.12 0.64-0.32 1.34-0.32 1.25 4.353 1.7 6 1.7 2.43 0 6.313-0.456 5.98-1.7-0.52-1.94-0.208-1.71-0.98-2.3-1.09-0.654-2.452-1.167-3.6-1.6-0.15-0.557-0.04-0.97 0.1-1.5 0.235-0.25 0.5-0.36 0.72-0.6 0.69-0.884 0.78-2.424 0.78-3.5 0-1.586-1.43-2.8-3-2.8z"/></svg>
diff --git a/theme/black/wizard-groupware@2x.png b/theme/black/wizard-groupware@2x.png
new file mode 100644
index 000000000..b9d544966
--- /dev/null
+++ b/theme/black/wizard-groupware@2x.png
Binary files differ
diff --git a/theme/black/wizard-nextcloud.png b/theme/black/wizard-nextcloud.png
new file mode 100644
index 000000000..1a7a6d83c
--- /dev/null
+++ b/theme/black/wizard-nextcloud.png
Binary files differ
diff --git a/theme/black/wizard-nextcloud.svg b/theme/black/wizard-nextcloud.svg
new file mode 100644
index 000000000..7b2a28341
--- /dev/null
+++ b/theme/black/wizard-nextcloud.svg
@@ -0,0 +1,81 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ version="1.1"
+ height="100"
+ width="200"
+ viewBox="0 0 200 100"
+ id="svg10"
+ sodipodi:docname="wizard-nextcloud.svg"
+ inkscape:export-filename="/home/felix/workspace/work/nextcloud-desktop/theme/white/wizard-nextcloud.png"
+ inkscape:export-xdpi="37.5"
+ inkscape:export-ydpi="37.5"
+ inkscape:version="1.0.2 (e86c870879, 2021-01-15)">
+ <metadata
+ id="metadata16">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <defs
+ id="defs14" />
+ <sodipodi:namedview
+ pagecolor="#808080"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="3440"
+ inkscape:window-height="1440"
+ id="namedview12"
+ showgrid="false"
+ inkscape:zoom="5.0976562"
+ inkscape:cx="63.321716"
+ inkscape:cy="64.000003"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:window-maximized="0"
+ inkscape:current-layer="svg10"
+ inkscape:document-rotation="0" />
+ <g
+ stroke="#000000"
+ stroke-width="22"
+ fill="none"
+ id="g8"
+ style="fill:#000000;fill-opacity:0"
+ transform="matrix(0.80267111,0,0,0.80443207,-2.7419032,-5.2833187)">
+ <circle
+ cy="64"
+ cx="40"
+ r="26"
+ id="circle2"
+ style="fill:#000000;fill-opacity:0" />
+ <circle
+ cy="64"
+ cx="216"
+ r="26"
+ id="circle4"
+ style="fill:#000000;fill-opacity:0" />
+ <circle
+ cy="64"
+ cx="128"
+ r="46"
+ id="circle6"
+ style="fill:#000000;fill-opacity:0" />
+ </g>
+</svg>
diff --git a/theme/black/wizard-nextcloud@2x.png b/theme/black/wizard-nextcloud@2x.png
new file mode 100644
index 000000000..0fbfc99f0
--- /dev/null
+++ b/theme/black/wizard-nextcloud@2x.png
Binary files differ
diff --git a/theme/black/wizard-talk.png b/theme/black/wizard-talk.png
new file mode 100644
index 000000000..5b512630f
--- /dev/null
+++ b/theme/black/wizard-talk.png
Binary files differ
diff --git a/theme/black/wizard-talk.svg b/theme/black/wizard-talk.svg
new file mode 100644
index 000000000..f81beb060
--- /dev/null
+++ b/theme/black/wizard-talk.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" height="16" width="16" version="1.1" viewBox="0 0 16 16"><path fill="#000000" d="m7.9992 0.999a6.9993 6.9994 0 0 0 -6.9992 6.9996 6.9993 6.9994 0 0 0 6.9992 6.9994 6.9993 6.9994 0 0 0 3.6308 -1.024c0.86024 0.34184 2.7871 1.356 3.2457 0.91794 0.47922-0.45765-0.56261-2.6116-0.81238-3.412a6.9993 6.9994 0 0 0 0.935 -3.4814 6.9993 6.9994 0 0 0 -6.9991 -6.9993zm0.0008 2.6611a4.34 4.3401 0 0 1 4.34 4.3401 4.34 4.3401 0 0 1 -4.34 4.3398 4.34 4.3401 0 0 1 -4.34 -4.3398 4.34 4.3401 0 0 1 4.34 -4.3401z" stroke-width="0.14"/></svg>
diff --git a/theme/black/wizard-talk@2x.png b/theme/black/wizard-talk@2x.png
new file mode 100644
index 000000000..8f77d93e5
--- /dev/null
+++ b/theme/black/wizard-talk@2x.png
Binary files differ
diff --git a/theme/colored/external.png b/theme/colored/external.png
new file mode 100644
index 000000000..21bb821e9
--- /dev/null
+++ b/theme/colored/external.png
Binary files differ
diff --git a/theme/colored/external.svg b/theme/colored/external.svg
new file mode 100644
index 000000000..7fa8f1a61
--- /dev/null
+++ b/theme/colored/external.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><path fill="#0082c9" d="M3.2 2C2.53 2 2 2.54 2 3.2v9.6c0 .67.53 1.2 1.2 1.2h9.6c.67 0 1.2-.53 1.2-1.2V8.98l-1.2-1.2v5.02H3.2V3.2h5.02L7.08 2.06 7.02 2H3.2z"/><path fill="#0082c9" d="M8.14 1l2.29 2.29L7 6.7 9.29 9l3.42-3.43L15 7.86V1z"/></svg>
diff --git a/theme/colored/external@2x.png b/theme/colored/external@2x.png
new file mode 100644
index 000000000..9e23cc497
--- /dev/null
+++ b/theme/colored/external@2x.png
Binary files differ
diff --git a/theme/colored/folder.png b/theme/colored/folder.png
new file mode 100644
index 000000000..2a5b34246
--- /dev/null
+++ b/theme/colored/folder.png
Binary files differ
diff --git a/theme/colored/folder.svg b/theme/colored/folder.svg
index c311e426b..2ee3ca7c8 100644
--- a/theme/colored/folder.svg
+++ b/theme/colored/folder.svg
@@ -1 +1 @@
-<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" version="1.1" height="16"><path fill="#0082c9" d="m1.5 2c-0.25 0-0.5 0.25-0.5 0.5v11c0 0.26 0.24 0.5 0.5 0.5h13c0.26 0 0.5-0.241 0.5-0.5v-9c0-0.25-0.25-0.5-0.5-0.5h-6.5l-2-2z"/></svg>
+<svg xmlns="http://www.w3.org/2000/svg" height="32" viewBox="0 0 32 32" width="32" version="1.1"><path fill="#0082c9" d="m3 4c-0.5 0-1 0.5-1 1v22c0 0.52 0.48 1 1 1h26c0.52 0 1-0.482 1-1v-18c0-0.5-0.5-1-1-1h-13l-4-4z"/></svg>
diff --git a/theme/colored/folder@2x.png b/theme/colored/folder@2x.png
new file mode 100644
index 000000000..1f7922839
--- /dev/null
+++ b/theme/colored/folder@2x.png
Binary files differ
diff --git a/theme/colored/wizard-files.png b/theme/colored/wizard-files.png
index 236bfa773..54b13fb15 100644
--- a/theme/colored/wizard-files.png
+++ b/theme/colored/wizard-files.png
Binary files differ
diff --git a/theme/colored/wizard-files@2x.png b/theme/colored/wizard-files@2x.png
index 4f1eb74ac..58a648cd6 100644
--- a/theme/colored/wizard-files@2x.png
+++ b/theme/colored/wizard-files@2x.png
Binary files differ
diff --git a/theme/colored/wizard-groupware.png b/theme/colored/wizard-groupware.png
index 417629bb9..034c078d5 100644
--- a/theme/colored/wizard-groupware.png
+++ b/theme/colored/wizard-groupware.png
Binary files differ
diff --git a/theme/colored/wizard-groupware@2x.png b/theme/colored/wizard-groupware@2x.png
index cea41d3c6..1aa5999a0 100644
--- a/theme/colored/wizard-groupware@2x.png
+++ b/theme/colored/wizard-groupware@2x.png
Binary files differ
diff --git a/theme/colored/wizard-nextcloud.png b/theme/colored/wizard-nextcloud.png
index 321f83e31..1f7903a65 100644
--- a/theme/colored/wizard-nextcloud.png
+++ b/theme/colored/wizard-nextcloud.png
Binary files differ
diff --git a/theme/colored/wizard-nextcloud.svg b/theme/colored/wizard-nextcloud.svg
index e92362c54..bc48cd582 100644
--- a/theme/colored/wizard-nextcloud.svg
+++ b/theme/colored/wizard-nextcloud.svg
@@ -1 +1,81 @@
-<svg xmlns="http://www.w3.org/2000/svg" version="1.1" height="128" width="256" viewBox="0 0 256 128" ><g stroke="#0082c9" stroke-width="22" fill="none"><circle cy="64" cx="40" r="26"/><circle cy="64" cx="216" r="26"/><circle cy="64" cx="128" r="46"/></g></svg>
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ version="1.1"
+ height="100"
+ width="200"
+ viewBox="0 0 200 100"
+ id="svg10"
+ sodipodi:docname="wizard-nextcloud.svg"
+ inkscape:export-filename="/home/felix/workspace/work/nextcloud-desktop/theme/white/wizard-nextcloud.png"
+ inkscape:export-xdpi="37.5"
+ inkscape:export-ydpi="37.5"
+ inkscape:version="1.0.2 (e86c870879, 2021-01-15)">
+ <metadata
+ id="metadata16">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <defs
+ id="defs14" />
+ <sodipodi:namedview
+ pagecolor="#808080"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="3440"
+ inkscape:window-height="1440"
+ id="namedview12"
+ showgrid="false"
+ inkscape:zoom="5.0976562"
+ inkscape:cx="63.321716"
+ inkscape:cy="64.000003"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:window-maximized="0"
+ inkscape:current-layer="svg10"
+ inkscape:document-rotation="0" />
+ <g
+ stroke="#0082c9"
+ stroke-width="22"
+ fill="none"
+ id="g8"
+ style="fill:#000000;fill-opacity:0"
+ transform="matrix(0.80267111,0,0,0.80443207,-2.7419032,-5.2833187)">
+ <circle
+ cy="64"
+ cx="40"
+ r="26"
+ id="circle2"
+ style="fill:#000000;fill-opacity:0" />
+ <circle
+ cy="64"
+ cx="216"
+ r="26"
+ id="circle4"
+ style="fill:#000000;fill-opacity:0" />
+ <circle
+ cy="64"
+ cx="128"
+ r="46"
+ id="circle6"
+ style="fill:#000000;fill-opacity:0" />
+ </g>
+</svg>
diff --git a/theme/colored/wizard-nextcloud@2x.png b/theme/colored/wizard-nextcloud@2x.png
index a73e467d8..da68bc6fb 100644
--- a/theme/colored/wizard-nextcloud@2x.png
+++ b/theme/colored/wizard-nextcloud@2x.png
Binary files differ
diff --git a/theme/colored/wizard-talk.png b/theme/colored/wizard-talk.png
index e1c3839a1..8231b27e0 100644
--- a/theme/colored/wizard-talk.png
+++ b/theme/colored/wizard-talk.png
Binary files differ
diff --git a/theme/colored/wizard-talk@2x.png b/theme/colored/wizard-talk@2x.png
index 92a368062..ccaa62f94 100644
--- a/theme/colored/wizard-talk@2x.png
+++ b/theme/colored/wizard-talk@2x.png
Binary files differ
diff --git a/theme/colored/wizard_logo.svg b/theme/colored/wizard_logo.svg
index f2c08adbf..8d86581d3 100644
--- a/theme/colored/wizard_logo.svg
+++ b/theme/colored/wizard_logo.svg
@@ -1,2 +1,2 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" height="126" viewBox="0 0 266.00001 126.0018" width="266" version="1.1" y="0px" x="0px" enable-background="new 0 0 196.6 72"><path style="color-rendering:auto;text-decoration-color:#000000;color:#000000;isolation:auto;mix-blend-mode:normal;shape-rendering:auto;solid-color:#000000;block-progression:tb;text-decoration-line:none;image-rendering:auto;white-space:normal;text-indent:0;enable-background:accumulate;text-transform:none;text-decoration-style:solid" fill="#fff" d="m134.19 6.1907c-26.05 0.0025-47.917 17.835-54.6 41.827-5.832-12.832-18.671-21.926-33.588-21.927-20.305 0.002-37 16.697-37.002 37.002-0.00364 20.309 16.693 37.008 37.002 37.01 14.918-0.002 27.748-9.1014 33.58-21.935 6.6801 23.995 28.558 41.832 54.608 41.834 25.904 0.002 47.668-17.641 54.486-41.43 5.9271 12.596 18.568 21.529 33.314 21.531 20.313 0.004 37.013-16.697 37.01-37.01-0.002-20.309-16.701-37.006-37.01-37.002-14.746 0.0017-27.395 8.933-33.321 21.531-6.81-23.79-28.57-41.433-54.47-41.431zm0 21.721c19.561-0.0013 35.186 15.62 35.188 35.181 0.001 19.563-15.625 35.19-35.188 35.188-19.56-0.001-35.182-15.627-35.18-35.188 0.002-19.559 15.62-35.179 35.18-35.181zm-88.188 19.9c8.5689 0.00099 15.28 6.7122 15.281 15.281 0.0015 8.5707-6.7103 15.288-15.281 15.289-8.5707-0.001-15.283-6.718-15.281-15.289 0.001-8.5689 6.7122-15.28 15.281-15.281zm175.99 0c8.5705-0.0015 15.288 6.7103 15.289 15.281 0.002 8.5726-6.7159 15.29-15.289 15.289-8.5708-0.001-15.283-6.718-15.281-15.289 0.00097-8.5689 6.7124-15.28 15.281-15.281z"/></svg>
+<svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" height="126" viewBox="0 0 266.00001 126.0018" width="266" version="1.1" y="0px" x="0px" enable-background="new 0 0 196.6 72"><path style="color-rendering:auto;text-decoration-color:#000000;color:#000000;isolation:auto;mix-blend-mode:normal;shape-rendering:auto;solid-color:#000000;block-progression:tb;text-decoration-line:none;image-rendering:auto;white-space:normal;text-indent:0;enable-background:accumulate;text-transform:none;text-decoration-style:solid" fill="#0082c9" d="m134.19 6.1907c-26.05 0.0025-47.917 17.835-54.6 41.827-5.832-12.832-18.671-21.926-33.588-21.927-20.305 0.002-37 16.697-37.002 37.002-0.00364 20.309 16.693 37.008 37.002 37.01 14.918-0.002 27.748-9.1014 33.58-21.935 6.6801 23.995 28.558 41.832 54.608 41.834 25.904 0.002 47.668-17.641 54.486-41.43 5.9271 12.596 18.568 21.529 33.314 21.531 20.313 0.004 37.013-16.697 37.01-37.01-0.002-20.309-16.701-37.006-37.01-37.002-14.746 0.0017-27.395 8.933-33.321 21.531-6.81-23.79-28.57-41.433-54.47-41.431zm0 21.721c19.561-0.0013 35.186 15.62 35.188 35.181 0.001 19.563-15.625 35.19-35.188 35.188-19.56-0.001-35.182-15.627-35.18-35.188 0.002-19.559 15.62-35.179 35.18-35.181zm-88.188 19.9c8.5689 0.00099 15.28 6.7122 15.281 15.281 0.0015 8.5707-6.7103 15.288-15.281 15.289-8.5707-0.001-15.283-6.718-15.281-15.289 0.001-8.5689 6.7122-15.28 15.281-15.281zm175.99 0c8.5705-0.0015 15.288 6.7103 15.289 15.281 0.002 8.5726-6.7159 15.29-15.289 15.289-8.5708-0.001-15.283-6.718-15.281-15.289 0.00097-8.5689 6.7124-15.28 15.281-15.281z"/></svg>
diff --git a/theme/sync-arrow.svg b/theme/sync-arrow.svg
new file mode 100644
index 000000000..56108b6d8
--- /dev/null
+++ b/theme/sync-arrow.svg
@@ -0,0 +1 @@
+<svg width="16" height="16" version="1.1" viewbox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path d="m4.0293 4.0003a1 1 0 0 0-0.73633 0.29297l-3 3a1.0001 1.0001 0 0 0 0 1.4141l3 3a1 1 0 0 0 1.4141 0 1 1 0 0 0 0-1.4141l-1.293-1.293h9.1719l-1.293 1.293a1 1 0 0 0 0 1.4141 1 1 0 0 0 1.4141 0l3-3a1.0001 1.0001 0 0 0 0-1.4141l-3-3a1 1 0 0 0-0.67773-0.29297 1 1 0 0 0-0.73633 0.29297 1 1 0 0 0 0 1.4141l1.293 1.293h-9.1719l1.293-1.293a1 1 0 0 0 0-1.4141 1 1 0 0 0-0.67773-0.29297z" fill="#969696"/></svg>
diff --git a/theme/white/external.png b/theme/white/external.png
new file mode 100644
index 000000000..bac44b1d8
--- /dev/null
+++ b/theme/white/external.png
Binary files differ
diff --git a/theme/white/external.svg b/theme/white/external.svg
new file mode 100644
index 000000000..892a4e5af
--- /dev/null
+++ b/theme/white/external.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><path fill="#ffffff" d="M3.2 2C2.53 2 2 2.54 2 3.2v9.6c0 .67.53 1.2 1.2 1.2h9.6c.67 0 1.2-.53 1.2-1.2V8.98l-1.2-1.2v5.02H3.2V3.2h5.02L7.08 2.06 7.02 2H3.2z"/><path fill="#ffffff" d="M8.14 1l2.29 2.29L7 6.7 9.29 9l3.42-3.43L15 7.86V1z"/></svg>
diff --git a/theme/white/external@2x.png b/theme/white/external@2x.png
new file mode 100644
index 000000000..5c49e615a
--- /dev/null
+++ b/theme/white/external@2x.png
Binary files differ
diff --git a/theme/white/folder.png b/theme/white/folder.png
new file mode 100644
index 000000000..cfeb3e1f6
--- /dev/null
+++ b/theme/white/folder.png
Binary files differ
diff --git a/theme/white/folder.svg b/theme/white/folder.svg
index 003e8b3fb..a32ffc857 100644
--- a/theme/white/folder.svg
+++ b/theme/white/folder.svg
@@ -1 +1 @@
-<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" version="1.1" height="16"><path fill="#fff" d="m1.5 2c-0.25 0-0.5 0.25-0.5 0.5v11c0 0.26 0.24 0.5 0.5 0.5h13c0.26 0 0.5-0.241 0.5-0.5v-9c0-0.25-0.25-0.5-0.5-0.5h-6.5l-2-2z"/></svg>
+<svg xmlns="http://www.w3.org/2000/svg" height="32" viewBox="0 0 32 32" width="32" version="1.1"><path fill="#ffffff" d="m3 4c-0.5 0-1 0.5-1 1v22c0 0.52 0.48 1 1 1h26c0.52 0 1-0.482 1-1v-18c0-0.5-0.5-1-1-1h-13l-4-4z"/></svg>
diff --git a/theme/white/folder@2x.png b/theme/white/folder@2x.png
new file mode 100644
index 000000000..03a919e6c
--- /dev/null
+++ b/theme/white/folder@2x.png
Binary files differ
diff --git a/theme/white/wizard-files.png b/theme/white/wizard-files.png
new file mode 100644
index 000000000..673a4bde2
--- /dev/null
+++ b/theme/white/wizard-files.png
Binary files differ
diff --git a/theme/white/wizard-files.svg b/theme/white/wizard-files.svg
new file mode 100644
index 000000000..e01fb5b88
--- /dev/null
+++ b/theme/white/wizard-files.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" height="16" viewBox="0 0 16 16" width="16" version="1.1"><path fill="#ffffff" d="m1.5 2c-0.25 0-0.5 0.25-0.5 0.5v11c0 0.26 0.24 0.5 0.5 0.5h13c0.26 0 0.5-0.241 0.5-0.5v-9c0-0.25-0.25-0.5-0.5-0.5h-6.5l-2-2h-4.5zm8.75 3.5a1.25 1.25 0 0 1 1.25 1.25 1.25 1.25 0 0 1 -1.25 1.25 1.25 1.25 0 0 1 -0.8008 -0.291l-2.4512 1.2265a1.25 1.25 0 0 1 0.002 0.0645 1.25 1.25 0 0 1 -0.0039 0.0645l2.4531 1.2265a1.25 1.25 0 0 1 0.8008 -0.291 1.25 1.25 0 0 1 1.25 1.25 1.25 1.25 0 0 1 -1.25 1.25 1.25 1.25 0 0 1 -1.25 -1.25 1.25 1.25 0 0 1 0.0039 -0.064l-2.4531-1.227a1.25 1.25 0 0 1 -0.8008 0.291 1.25 1.25 0 0 1 -1.25 -1.25 1.25 1.25 0 0 1 1.25 -1.25 1.25 1.25 0 0 1 0.8008 0.291l2.4512-1.2265a1.25 1.25 0 0 1 -0.002 -0.0645 1.25 1.25 0 0 1 1.25 -1.25z"/></svg>
diff --git a/theme/white/wizard-files@2x.png b/theme/white/wizard-files@2x.png
new file mode 100644
index 000000000..810030290
--- /dev/null
+++ b/theme/white/wizard-files@2x.png
Binary files differ
diff --git a/theme/white/wizard-groupware.png b/theme/white/wizard-groupware.png
new file mode 100644
index 000000000..e348accb2
--- /dev/null
+++ b/theme/white/wizard-groupware.png
Binary files differ
diff --git a/theme/white/wizard-groupware.svg b/theme/white/wizard-groupware.svg
new file mode 100644
index 000000000..0cd9a33e5
--- /dev/null
+++ b/theme/white/wizard-groupware.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 16 16" height="16" width="16" version="1.1"><path fill="#ffffff" d="m9 1c-1.746 0-3 1.43-3 2.8 0 1.4 0.1 2.4 0.8 3.5 0.224 0.29 0.485 0.35 0.7 0.6 0.135 0.5 0.24 1 0.1 1.5-0.436 0.153-0.85 0.332-1.27 0.5-0.51-0.273-1.1-0.5-1.61-0.7-0.07-0.28-0.02-0.487 0.05-0.75 0.12-0.125 0.23-0.18 0.36-0.3 0.37-0.45 0.39-1.21 0.39-1.75 0-0.8-0.72-1.4-1.5-1.4-0.87 0-1.5 0.72-1.5 1.4h-0.02c0 0.7 0.05 1.2 0.4 1.75 0.1 0.15 0.242 0.175 0.35 0.3 0.0674 0.25 0.121 0.5 0.05 0.75-0.64 0.223-1.244 0.5-1.8 0.8-0.42 0.3-0.233 0.182-0.5 1.15-0.124 0.5 1.3 0.73 2.32 0.81-0.05 0.275-0.12 0.64-0.32 1.34-0.32 1.25 4.353 1.7 6 1.7 2.43 0 6.313-0.456 5.98-1.7-0.52-1.94-0.208-1.71-0.98-2.3-1.09-0.654-2.452-1.167-3.6-1.6-0.15-0.557-0.04-0.97 0.1-1.5 0.235-0.25 0.5-0.36 0.72-0.6 0.69-0.884 0.78-2.424 0.78-3.5 0-1.586-1.43-2.8-3-2.8z"/></svg>
diff --git a/theme/white/wizard-groupware@2x.png b/theme/white/wizard-groupware@2x.png
new file mode 100644
index 000000000..ae5024e44
--- /dev/null
+++ b/theme/white/wizard-groupware@2x.png
Binary files differ
diff --git a/theme/white/wizard-nextcloud.png b/theme/white/wizard-nextcloud.png
new file mode 100644
index 000000000..8022b79a3
--- /dev/null
+++ b/theme/white/wizard-nextcloud.png
Binary files differ
diff --git a/theme/white/wizard-nextcloud.svg b/theme/white/wizard-nextcloud.svg
new file mode 100644
index 000000000..a0330d783
--- /dev/null
+++ b/theme/white/wizard-nextcloud.svg
@@ -0,0 +1,81 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ version="1.1"
+ height="100"
+ width="200"
+ viewBox="0 0 200 100"
+ id="svg10"
+ sodipodi:docname="wizard-nextcloud.svg"
+ inkscape:export-filename="/home/felix/workspace/work/nextcloud-desktop/theme/white/wizard-nextcloud.png"
+ inkscape:export-xdpi="37.5"
+ inkscape:export-ydpi="37.5"
+ inkscape:version="1.0.2 (e86c870879, 2021-01-15)">
+ <metadata
+ id="metadata16">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <defs
+ id="defs14" />
+ <sodipodi:namedview
+ pagecolor="#808080"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="3440"
+ inkscape:window-height="1440"
+ id="namedview12"
+ showgrid="false"
+ inkscape:zoom="5.0976562"
+ inkscape:cx="63.321716"
+ inkscape:cy="64.000003"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:window-maximized="0"
+ inkscape:current-layer="svg10"
+ inkscape:document-rotation="0" />
+ <g
+ stroke="#ffffff"
+ stroke-width="22"
+ fill="none"
+ id="g8"
+ style="fill:#000000;fill-opacity:0"
+ transform="matrix(0.80267111,0,0,0.80443207,-2.7419032,-5.2833187)">
+ <circle
+ cy="64"
+ cx="40"
+ r="26"
+ id="circle2"
+ style="fill:#000000;fill-opacity:0" />
+ <circle
+ cy="64"
+ cx="216"
+ r="26"
+ id="circle4"
+ style="fill:#000000;fill-opacity:0" />
+ <circle
+ cy="64"
+ cx="128"
+ r="46"
+ id="circle6"
+ style="fill:#000000;fill-opacity:0" />
+ </g>
+</svg>
diff --git a/theme/white/wizard-nextcloud@2x.png b/theme/white/wizard-nextcloud@2x.png
new file mode 100644
index 000000000..ad10827c2
--- /dev/null
+++ b/theme/white/wizard-nextcloud@2x.png
Binary files differ
diff --git a/theme/white/wizard-talk.png b/theme/white/wizard-talk.png
new file mode 100644
index 000000000..fc4646fe0
--- /dev/null
+++ b/theme/white/wizard-talk.png
Binary files differ
diff --git a/theme/white/wizard-talk.svg b/theme/white/wizard-talk.svg
new file mode 100644
index 000000000..45ab71d99
--- /dev/null
+++ b/theme/white/wizard-talk.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" height="16" width="16" version="1.1" viewBox="0 0 16 16"><path fill="#ffffff" d="m7.9992 0.999a6.9993 6.9994 0 0 0 -6.9992 6.9996 6.9993 6.9994 0 0 0 6.9992 6.9994 6.9993 6.9994 0 0 0 3.6308 -1.024c0.86024 0.34184 2.7871 1.356 3.2457 0.91794 0.47922-0.45765-0.56261-2.6116-0.81238-3.412a6.9993 6.9994 0 0 0 0.935 -3.4814 6.9993 6.9994 0 0 0 -6.9991 -6.9993zm0.0008 2.6611a4.34 4.3401 0 0 1 4.34 4.3401 4.34 4.3401 0 0 1 -4.34 4.3398 4.34 4.3401 0 0 1 -4.34 -4.3398 4.34 4.3401 0 0 1 4.34 -4.3401z" stroke-width="0.14"/></svg>
diff --git a/theme/white/wizard-talk@2x.png b/theme/white/wizard-talk@2x.png
new file mode 100644
index 000000000..b576ec365
--- /dev/null
+++ b/theme/white/wizard-talk@2x.png
Binary files differ