(_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("Warning: The local folder is not empty. "
- "Pick a resolution!
");
+ 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(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 7fcde225a716..8af948d9cc47 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 slots:
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 slots:
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 3b3b688dd80f..075de08409c7 100644
--- a/src/gui/wizard/owncloudadvancedsetuppage.ui
+++ b/src/gui/wizard/owncloudadvancedsetuppage.ui
@@ -11,7 +11,7 @@
-
+
0
0
@@ -48,7 +48,7 @@
Qt::Vertical
- QSizePolicy::Fixed
+ QSizePolicy::Expanding
@@ -59,9 +59,291 @@
-
-
-
-
-
+
+
+ 0
+
+
-
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ 0
+
+
-
+
+
-
+
+
+ Qt::Vertical
+
+
+ QSizePolicy::Expanding
+
+
+
+ 20
+ 40
+
+
+
+
+ -
+
+
+ Avatar
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+
+ 75
+ true
+
+
+
+ User name
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+ Server address
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+ QSizePolicy::Expanding
+
+
+
+ 20
+ 40
+
+
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+ QSizePolicy::Minimum
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ Sync Logo
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+ QSizePolicy::Minimum
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
-
+
+
+ Qt::Vertical
+
+
+ QSizePolicy::Expanding
+
+
+
+ 20
+ 40
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ &Local Folder
+
+
+ Qt::AlignCenter
+
+
+ pbSelectLocalFolder
+
+
+
+ -
+
+
+
+ 75
+ true
+
+
+
+ Local Folder
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+ 0
+
+
-
+
+
+ Qt::Horizontal
+
+
+ QSizePolicy::Minimum
+
+
+
+ 0
+ 20
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ pbSelectLocalFolder
+
+
+ true
+
+
+ false
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+ QSizePolicy::Minimum
+
+
+
+ 0
+ 20
+
+
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ Free space
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+ QSizePolicy::Expanding
+
+
+
+ 20
+ 40
+
+
+
+
+
+
+
+
+ -
+
Qt::Horizontal
@@ -73,378 +355,428 @@
- -
-
-
-
- 0
-
-
- 0
-
-
-
-
+
+
+ -
+
+
+ QLayout::SetMinimumSize
+
+
+ 0
+
+
+ 0
+
+
-
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ 0
+
+
+ 0
+
+
-
+
+
+ 0
+
+
+ 0
+
+
-
+
+
+ 0
+
+
-
+
+
+ Synchronize everything from server
+
+
+ true
+
+
+
+ -
+
+
+ Size
+
+
+ Qt::PlainText
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+ -
+
+
+ 0
+
+
-
+
+
+ Qt::Horizontal
+
+
+ QSizePolicy::Minimum
+
+
+
+ 20
+ 20
+
+
+
+
+ -
+
+
+ Ask before syncing folders larger than
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ Qt::StrongFocus
+
+
+ 999999
+
+
+ 99
+
+
+
+ -
+
+
+ MB
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+ -
+
+
+ 0
+
+
-
+
+
+ Qt::Horizontal
+
+
+ QSizePolicy::Minimum
+
+
+
+ 20
+ 20
+
+
+
+
+ -
+
+
+ Ask before syncing external storages
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+ -
+
+
+ 0
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+
+
+
+ false
+
+
+
+ -
+
+
+ Choose what to sync
+
+
+ true
+
+
+ false
+
+
+
+ -
+
+
+ TextLabel
+
+
+ Qt::PlainText
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+ -
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+ Use virtual files !PLACEHOLDER!
+
+
+ false
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 6
+
+
+ QLayout::SetMinimumSize
+
+
+ 0
+
+
+ 2
+
+
+ 0
+
+
+ 0
+
-
-
-
- S&ynchronize everything from server
+
+
+
+ 0
+ 0
+
-
- true
+
+
+ 9
+ 75
+ true
+
+
+
+ 1
-
-
- -
-
- TextLabel
+ Status message
- Qt::PlainText
+ Qt::AutoText
-
-
- -
-
-
- Qt::Horizontal
-
-
-
- 40
- 20
-
-
-
-
-
-
- -
-
-
- 0
-
-
-
-
-
- Qt::Horizontal
+
+ Qt::AlignCenter
-
- QSizePolicy::Minimum
-
-
-
- 10
- 20
-
-
-
-
- -
-
-
-
-
-
- Ask for confirmation before synchroni&zing folders larger than
-
-
-
- -
-
-
- 999999
-
-
- 99
-
-
-
- -
-
-
- MB
-
-
-
-
-
- -
-
-
- Ask for confirmation before synchronizing e&xternal storages
+
+ false
-
-
- -
-
-
-
+
-
+
0
0
-
-
-
- false
-
-
-
- -
-
-
- Choose what to sync
-
-
-
- -
-
-
- TextLabel
+ Keep local data
-
- Qt::PlainText
+
+ true
-
-
-
- Qt::Horizontal
-
-
-
- 40
- 20
-
-
-
-
-
-
- -
-
-
-
-
+
-
+
0
0
+
+ <html><head/><body><p>If this box is checked, existing content in the local folder will be erased to start a clean sync from the server.</p><p>Do not check this if the local content should be uploaded to the servers folder.</p></body></html>
+
- Use &virtual files !PLACEHOLDER!
+ Erase local folder and start a clean sync
- false
+ true
- -
-
-
- Qt::Horizontal
-
-
-
- 40
- 20
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
- TextLabel
-
-
- Qt::AlignCenter
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
- &Local Folder
-
-
- Qt::AlignCenter
-
-
- pbSelectLocalFolder
-
- -
-
-
- Qt::Vertical
-
-
-
- 20
- 40
-
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
- pbSelectLocalFolder
-
-
-
- -
-
-
-
-
-
- TextLabel
-
-
- Qt::AlignCenter
-
-
-
- -
-
-
- Server
-
-
- Qt::AlignCenter
-
-
-
- -
-
-
- Qt::Vertical
-
-
-
- 20
- 40
-
-
-
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
-
- QLayout::SetMinimumSize
-
-
- QFormLayout::ExpandingFieldsGrow
-
-
-
-
-
- &Keep local data
-
-
- true
-
-
-
- -
-
-
- <html><head/><body><p>If this box is checked, existing content in the local folder will be erased to start a clean sync from the server.</p><p>Do not check this if the local content should be uploaded to the servers folder.</p></body></html>
-
-
- Start a &clean sync (Erases the local folder!)
-
-
- true
-
-
-
-
-
-
- -
-
+
-
+
- Qt::Vertical
-
-
- QSizePolicy::MinimumExpanding
+ Qt::Horizontal
- 20
- 40
+ 40
+ 20
- -
-
-
- TextLabel
-
-
-
-
-
-
- TextLabel
+
+
+ Qt::Vertical
-
+
+ QSizePolicy::Expanding
+
+
+
+ 20
+ 40
+
+
+
-
-
+
- Status message
-
-
- Qt::RichText
-
-
- Qt::AlignCenter
-
-
- true
+ TextLabel
diff --git a/src/gui/wizard/owncloudsetupnocredspage.ui b/src/gui/wizard/owncloudsetupnocredspage.ui
index d3e62595e06d..d67873450da9 100644
--- a/src/gui/wizard/owncloudsetupnocredspage.ui
+++ b/src/gui/wizard/owncloudsetupnocredspage.ui
@@ -6,12 +6,12 @@
0
0
- 802
- 629
+ 556
+ 489
-
+
0
0
@@ -27,102 +27,84 @@
-
-
+
+
+ TextLabel
+
+
+
+ -
+
Qt::Vertical
- QSizePolicy::MinimumExpanding
+ QSizePolicy::Expanding
20
- 20
+ 80
-
-
-
-
- 0
- 0
-
-
-
- TextLabel
-
-
- Qt::RichText
-
-
- Qt::AlignCenter
-
-
- true
+
+
+ 0
-
-
- -
-
-
-
-
-
- 40
- 0
-
+
+
+ Qt::Horizontal
-
+
- 40
- 16777215
+ 0
+ 0
-
-
-
-
- true
-
-
+
-
-
-
-
- 12
- 75
- true
-
+
+
+ Logo
-
-
-
-
- 40
- 0
-
+
+
+ Qt::Horizontal
-
+
- 40
- 16777215
+ 0
+ 0
-
-
-
-
- true
-
-
+
+ -
+
+
+ Qt::Vertical
+
+
+ QSizePolicy::Minimum
+
+
+
+ 0
+ 0
+
+
+
+
-
@@ -143,38 +125,28 @@
-
+
+ 0
+
QLayout::SetDefaultConstraint
-
-
-
-
- Qt::Horizontal
-
-
- QSizePolicy::Preferred
-
-
-
- 40
- 0
-
-
-
-
-
+
+ 6
+
-
Qt::Vertical
- QSizePolicy::MinimumExpanding
+ QSizePolicy::Minimum
- 20
+ 0
0
@@ -182,73 +154,138 @@
-
+
+ 0
+
-
-
-
-
- 0
- 0
-
+
+
+ Qt::Horizontal
-
- Server Address
+
+
+ 0
+ 0
+
-
- leUrl
+
+
+ -
+
+
+
+ 12
+ 75
+ true
+
+
+
+ Server address
-
-
-
-
- 0
- 0
-
+
+
+ Qt::Horizontal
-
-
+
+
+ 0
+ 0
+
-
+
+
+
+
+ -
+
+
+ 0
+
+
-
+
+
+ Qt::Horizontal
+
+
+ QSizePolicy::Expanding
+
+
+
+ 80
+ 0
+
+
+
-
-
-
+
+
+ 8
+
+
0
+
-
+
+
+
+ 0
+ 0
+
+
+
+
+ 200
+ 0
+
+
+
+ https://try.nextcloud.com
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ This is the link to your %1 web interface when you open it in the browser.
+
+
+ Qt::AlignCenter
+
+
+ true
+
+
+
-
-
-
-
- 0
- 0
-
+
+
+ Qt::Horizontal
+
+
+ QSizePolicy::Expanding
-
+
- 24
- 24
+ 80
+ 0
-
-
-
-
+
- -
-
-
- 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
-
-
- true
-
-
-
-
@@ -268,6 +305,9 @@
+ -
+
+
-
@@ -278,7 +318,7 @@
- 20
+ 0
0
@@ -286,22 +326,6 @@
- -
-
-
- Qt::Horizontal
-
-
- QSizePolicy::Preferred
-
-
-
- 40
- 0
-
-
-
-
@@ -317,163 +341,26 @@
- 20
- 20
+ 0
+ 0
-
-
-
- 6
-
-
- 20
+
+
+ TextLabel
-
-
-
-
- Qt::Horizontal
-
-
-
- 40
- 20
-
-
-
-
- -
-
-
-
- 150
- 0
-
-
-
- false
-
-
- Sign up with a provider
-
-
- false
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
-
- 150
- 0
-
-
-
- Log in to your %1
-
-
- false
-
-
- true
-
-
- false
-
-
-
- -
-
-
- Qt::Horizontal
-
-
-
- 40
- 20
-
-
-
-
-
+
-
0
-
-
-
-
- Qt::Horizontal
-
-
-
- 40
- 20
-
-
-
-
- -
-
-
-
-
-
-
- <a href="https://docs.nextcloud.com/server/latest/admin_manual/installation/#installation"><span style=" text-decoration: underline; color:#7a7a7a;">Host your own server</span></a>
-
-
- true
-
-
- Qt::LinksAccessibleByKeyboard|Qt::LinksAccessibleByMouse
-
-
-
-
-
-
- -
-
-
- Qt::Horizontal
-
-
-
- 40
- 20
-
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
- TextLabel
-
-
- Qt::RichText
-
-
-
@@ -482,11 +369,6 @@
QLineEdit
-
- OCC::SlideShow
- QWidget
-
-
diff --git a/src/gui/wizard/owncloudsetuppage.cpp b/src/gui/wizard/owncloudsetuppage.cpp
index eff655e000c3..800d965d65df 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.
"
- "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(_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(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 18b9c0135dc0..485a2bd62203 100644
--- a/src/gui/wizard/owncloudsetuppage.h
+++ b/src/gui/wizard/owncloudsetuppage.h
@@ -78,7 +78,9 @@ protected slots:
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 d97b0b19fd50..4a8e3866204d 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 OwncloudWizard::calculateWizardPageSizes() const
+{
+ QList 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 &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(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 947d5f679ff2..e8480d3bda70 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 @@ class OwncloudWizard : public QWizard
AbstractCredentials *getCredentials() const;
void bringToTop();
+ void centerWindow();
/**
* Shows a dialog explaining the virtual files mode and warning about it
@@ -113,8 +115,12 @@ public slots:
private:
void customizeStyle();
+ void adjustWizardSize();
+ int calculateLongestSideOfWizardPages(const QList &pageSizes) const;
+ QList 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 56768209bc99..0f473508243b 100644
--- a/src/gui/wizard/owncloudwizardcommon.cpp
+++ b/src/gui/wizard/owncloudwizardcommon.cpp
@@ -16,6 +16,10 @@
#include
#include
#include
+#include
+#include
+#include
+#include
#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 d1f7c08be07a..5ebcca01fc95 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
+
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 ba3588ca8776..8ab0665b7871 100644
--- a/src/gui/wizard/webview.ui
+++ b/src/gui/wizard/webview.ui
@@ -11,15 +11,15 @@
-
+
0
0
- 800
- 650
+ 0
+ 0
diff --git a/src/gui/wizard/webviewpage.cpp b/src/gui/wizard/webviewpage.cpp
index 01311e839bf6..7aae73fc8866 100644
--- a/src/gui/wizard/webviewpage.cpp
+++ b/src/gui/wizard/webviewpage.cpp
@@ -4,6 +4,7 @@
#include
#include
#include
+#include
#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(_originalWizardSize.width() * 1.5), static_cast(_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 65f00c33bb96..c621e99f1e26 100644
--- a/src/gui/wizard/webviewpage.h
+++ b/src/gui/wizard/webviewpage.h
@@ -17,6 +17,7 @@ class WebViewPage : public AbstractCredentialsWizardPage
~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 slots:
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 000000000000..668c5b02f56f
--- /dev/null
+++ b/src/gui/wizard/welcomepage.cpp
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2021 by Felix Weilbach
+ *
+ * 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 000000000000..9d0aa1c0a849
--- /dev/null
+++ b/src/gui/wizard/welcomepage.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2021 by Felix Weilbach
+ *
+ * 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
+
+#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;
+
+ 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 000000000000..1d54a802754d
--- /dev/null
+++ b/src/gui/wizard/welcomepage.ui
@@ -0,0 +1,229 @@
+
+
+ OCC::WelcomePage
+
+
+
+ 0
+ 0
+ 500
+ 500
+
+
+
+
+ 0
+ 0
+
+
+
+ Form
+
+
+ -
+
+
+ Qt::Vertical
+
+
+ QSizePolicy::Expanding
+
+
+
+ 20
+ 80
+
+
+
+
+ -
+
+
+ 0
+
+
-
+
+
+
+ 40
+ 16777215
+
+
+
+
+
+
+ false
+
+
+ false
+
+
+ true
+
+
+
+ -
+
+
+
+ 12
+ 75
+ true
+
+
+
+
+ -
+
+
+
+ 40
+ 16777215
+
+
+
+
+
+
+ false
+
+
+ false
+
+
+ true
+
+
+
+
+
+ -
+
+
+ 0
+
+
+ 0
+
+
-
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ 0
+
+
-
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 40
+
+
+
+
+ -
+
+
+ Log in to your %1
+
+
+ true
+
+
+ true
+
+
+
+ -
+
+
+ Create account with Provider
+
+
+ true
+
+
+ false
+
+
+
+ -
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 40
+
+
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 40
+
+
+
+
+
+
+
+
+ OCC::SlideShow
+ QWidget
+
+
+
+ OCC::LinkLabel
+ QWidget
+
+ 1
+
+
+
+
+
diff --git a/src/libsync/nextcloudtheme.cpp b/src/libsync/nextcloudtheme.cpp
index 0ec3f2d27398..2a709564c6e4 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 be3bde5e6a5d..b77a6665593e 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 394cb8930537..a06828b1fcb4 100644
--- a/src/libsync/theme.h
+++ b/src/libsync/theme.h
@@ -132,6 +132,10 @@ class OWNCLOUDSYNC_EXPORT Theme : public QObject
#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 @@ class OWNCLOUDSYNC_EXPORT Theme : public QObject
/** @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 2297eb0da89e..9dcc1730de11 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 000000000000..52bc7b324d49
--- /dev/null
+++ b/test/testtheme.cpp
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2021 by Felix Weilbach
+ *
+ * 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
+
+#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 000000000000..763d58a1f997
--- /dev/null
+++ b/test/themeutils.cpp
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2021 by Felix Weilbach
+ *
+ * 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 000000000000..4e8327e54a14
--- /dev/null
+++ b/test/themeutils.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) by Felix Weilbach
+ *
+ * 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
+#include
+
+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 7d0c732b8e23..620a406027b9 100644
--- a/theme.qrc
+++ b/theme.qrc
@@ -80,6 +80,12 @@
theme/colored/state-warning-64.png
theme/colored/state-warning-128.png
theme/colored/state-warning-256.png
+ theme/black/folder.png
+ theme/black/folder@2x.png
+ theme/white/folder.png
+ theme/white/folder@2x.png
+ theme/colored/folder.png
+ theme/colored/folder@2x.png
theme/black/control-next.svg
theme/black/control-prev.svg
theme/black/state-error.svg
@@ -124,6 +130,23 @@
theme/white/state-warning-64.png
theme/white/state-warning-128.png
theme/white/state-warning-256.png
+ theme/white/wizard-files.png
+ theme/white/wizard-files@2x.png
+ theme/white/wizard-groupware.png
+ theme/white/wizard-groupware@2x.png
+ theme/white/wizard-nextcloud.png
+ theme/white/wizard-nextcloud@2x.png
+ theme/white/wizard-talk.png
+ theme/white/wizard-talk@2x.png
+ theme/black/wizard-files.png
+ theme/black/wizard-files@2x.png
+ theme/black/wizard-groupware.png
+ theme/black/wizard-groupware@2x.png
+ theme/black/wizard-nextcloud.png
+ theme/black/wizard-nextcloud@2x.png
+ theme/black/wizard-talk.png
+ theme/black/wizard-talk@2x.png
+ theme/black/wizard-files.png
theme/colored/wizard-files.png
theme/colored/wizard-files@2x.png
theme/colored/wizard-groupware.png
@@ -132,6 +155,13 @@
theme/colored/wizard-nextcloud@2x.png
theme/colored/wizard-talk.png
theme/colored/wizard-talk@2x.png
+ theme/sync-arrow.svg
+ theme/white/external.png
+ theme/white/external@2x.png
+ theme/black/external.png
+ theme/black/external@2x.png
+ theme/colored/external.png
+ theme/colored/external@2x.png
theme/white/folder.svg
theme/white/more-apps.svg
theme/white/talk-app.svg
diff --git a/theme/black/external.png b/theme/black/external.png
new file mode 100644
index 000000000000..db82098ecd55
Binary files /dev/null and b/theme/black/external.png differ
diff --git a/theme/black/external.svg b/theme/black/external.svg
new file mode 100644
index 000000000000..79c9cebf5889
--- /dev/null
+++ b/theme/black/external.svg
@@ -0,0 +1 @@
+
\ 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 000000000000..04779d85945a
Binary files /dev/null and b/theme/black/external@2x.png differ
diff --git a/theme/black/folder.png b/theme/black/folder.png
new file mode 100644
index 000000000000..3d67f6ec2f0a
Binary files /dev/null and b/theme/black/folder.png differ
diff --git a/theme/black/folder.svg b/theme/black/folder.svg
new file mode 100644
index 000000000000..9289fb05d74c
--- /dev/null
+++ b/theme/black/folder.svg
@@ -0,0 +1 @@
+
diff --git a/theme/black/folder@2x.png b/theme/black/folder@2x.png
new file mode 100644
index 000000000000..2ac972b9a830
Binary files /dev/null and b/theme/black/folder@2x.png differ
diff --git a/theme/black/wizard-files.png b/theme/black/wizard-files.png
new file mode 100644
index 000000000000..01c6a2540ce7
Binary files /dev/null and b/theme/black/wizard-files.png differ
diff --git a/theme/black/wizard-files.svg b/theme/black/wizard-files.svg
new file mode 100644
index 000000000000..6c3ff3761017
--- /dev/null
+++ b/theme/black/wizard-files.svg
@@ -0,0 +1 @@
+
diff --git a/theme/black/wizard-files@2x.png b/theme/black/wizard-files@2x.png
new file mode 100644
index 000000000000..30a6ddfaff34
Binary files /dev/null and b/theme/black/wizard-files@2x.png differ
diff --git a/theme/black/wizard-groupware.png b/theme/black/wizard-groupware.png
new file mode 100644
index 000000000000..f560466a2733
Binary files /dev/null and b/theme/black/wizard-groupware.png differ
diff --git a/theme/black/wizard-groupware.svg b/theme/black/wizard-groupware.svg
new file mode 100644
index 000000000000..f7f31340b043
--- /dev/null
+++ b/theme/black/wizard-groupware.svg
@@ -0,0 +1 @@
+
diff --git a/theme/black/wizard-groupware@2x.png b/theme/black/wizard-groupware@2x.png
new file mode 100644
index 000000000000..b9d544966db5
Binary files /dev/null and b/theme/black/wizard-groupware@2x.png differ
diff --git a/theme/black/wizard-nextcloud.png b/theme/black/wizard-nextcloud.png
new file mode 100644
index 000000000000..1a7a6d83c709
Binary files /dev/null and b/theme/black/wizard-nextcloud.png differ
diff --git a/theme/black/wizard-nextcloud.svg b/theme/black/wizard-nextcloud.svg
new file mode 100644
index 000000000000..7b2a28341d54
--- /dev/null
+++ b/theme/black/wizard-nextcloud.svg
@@ -0,0 +1,81 @@
+
+
diff --git a/theme/black/wizard-nextcloud@2x.png b/theme/black/wizard-nextcloud@2x.png
new file mode 100644
index 000000000000..0fbfc99f048d
Binary files /dev/null and b/theme/black/wizard-nextcloud@2x.png differ
diff --git a/theme/black/wizard-talk.png b/theme/black/wizard-talk.png
new file mode 100644
index 000000000000..5b512630f9a5
Binary files /dev/null and b/theme/black/wizard-talk.png differ
diff --git a/theme/black/wizard-talk.svg b/theme/black/wizard-talk.svg
new file mode 100644
index 000000000000..f81beb060fdf
--- /dev/null
+++ b/theme/black/wizard-talk.svg
@@ -0,0 +1 @@
+
diff --git a/theme/black/wizard-talk@2x.png b/theme/black/wizard-talk@2x.png
new file mode 100644
index 000000000000..8f77d93e559e
Binary files /dev/null and b/theme/black/wizard-talk@2x.png differ
diff --git a/theme/colored/external.png b/theme/colored/external.png
new file mode 100644
index 000000000000..21bb821e945a
Binary files /dev/null and b/theme/colored/external.png differ
diff --git a/theme/colored/external.svg b/theme/colored/external.svg
new file mode 100644
index 000000000000..7fa8f1a61f0a
--- /dev/null
+++ b/theme/colored/external.svg
@@ -0,0 +1 @@
+
diff --git a/theme/colored/external@2x.png b/theme/colored/external@2x.png
new file mode 100644
index 000000000000..9e23cc497900
Binary files /dev/null and b/theme/colored/external@2x.png differ
diff --git a/theme/colored/folder.png b/theme/colored/folder.png
new file mode 100644
index 000000000000..2a5b34246740
Binary files /dev/null and b/theme/colored/folder.png differ
diff --git a/theme/colored/folder.svg b/theme/colored/folder.svg
index c311e426b664..2ee3ca7c8951 100644
--- a/theme/colored/folder.svg
+++ b/theme/colored/folder.svg
@@ -1 +1 @@
-
+
diff --git a/theme/colored/folder@2x.png b/theme/colored/folder@2x.png
new file mode 100644
index 000000000000..1f79228397da
Binary files /dev/null and b/theme/colored/folder@2x.png differ
diff --git a/theme/colored/wizard-files.png b/theme/colored/wizard-files.png
index 236bfa773706..54b13fb15326 100644
Binary files a/theme/colored/wizard-files.png and b/theme/colored/wizard-files.png differ
diff --git a/theme/colored/wizard-files@2x.png b/theme/colored/wizard-files@2x.png
index 4f1eb74acb8b..58a648cd613c 100644
Binary files a/theme/colored/wizard-files@2x.png and b/theme/colored/wizard-files@2x.png differ
diff --git a/theme/colored/wizard-groupware.png b/theme/colored/wizard-groupware.png
index 417629bb9df1..034c078d5525 100644
Binary files a/theme/colored/wizard-groupware.png and b/theme/colored/wizard-groupware.png differ
diff --git a/theme/colored/wizard-groupware@2x.png b/theme/colored/wizard-groupware@2x.png
index cea41d3c614b..1aa5999a0031 100644
Binary files a/theme/colored/wizard-groupware@2x.png and b/theme/colored/wizard-groupware@2x.png differ
diff --git a/theme/colored/wizard-nextcloud.png b/theme/colored/wizard-nextcloud.png
index 321f83e31ab4..1f7903a655bc 100644
Binary files a/theme/colored/wizard-nextcloud.png and b/theme/colored/wizard-nextcloud.png differ
diff --git a/theme/colored/wizard-nextcloud.svg b/theme/colored/wizard-nextcloud.svg
index e92362c5455b..bc48cd582ee7 100644
--- a/theme/colored/wizard-nextcloud.svg
+++ b/theme/colored/wizard-nextcloud.svg
@@ -1 +1,81 @@
-
+
+
diff --git a/theme/colored/wizard-nextcloud@2x.png b/theme/colored/wizard-nextcloud@2x.png
index a73e467d8a12..da68bc6fbf99 100644
Binary files a/theme/colored/wizard-nextcloud@2x.png and b/theme/colored/wizard-nextcloud@2x.png differ
diff --git a/theme/colored/wizard-talk.png b/theme/colored/wizard-talk.png
index e1c3839a1692..8231b27e0dba 100644
Binary files a/theme/colored/wizard-talk.png and b/theme/colored/wizard-talk.png differ
diff --git a/theme/colored/wizard-talk@2x.png b/theme/colored/wizard-talk@2x.png
index 92a368062294..ccaa62f9491c 100644
Binary files a/theme/colored/wizard-talk@2x.png and b/theme/colored/wizard-talk@2x.png differ
diff --git a/theme/colored/wizard_logo.svg b/theme/colored/wizard_logo.svg
index f2c08adbf22c..8d86581d3a0f 100644
--- a/theme/colored/wizard_logo.svg
+++ b/theme/colored/wizard_logo.svg
@@ -1,2 +1,2 @@
-
+
diff --git a/theme/sync-arrow.svg b/theme/sync-arrow.svg
new file mode 100644
index 000000000000..56108b6d84f0
--- /dev/null
+++ b/theme/sync-arrow.svg
@@ -0,0 +1 @@
+
diff --git a/theme/white/external.png b/theme/white/external.png
new file mode 100644
index 000000000000..bac44b1d8113
Binary files /dev/null and b/theme/white/external.png differ
diff --git a/theme/white/external.svg b/theme/white/external.svg
new file mode 100644
index 000000000000..892a4e5afc38
--- /dev/null
+++ b/theme/white/external.svg
@@ -0,0 +1 @@
+
diff --git a/theme/white/external@2x.png b/theme/white/external@2x.png
new file mode 100644
index 000000000000..5c49e615ae90
Binary files /dev/null and b/theme/white/external@2x.png differ
diff --git a/theme/white/folder.png b/theme/white/folder.png
new file mode 100644
index 000000000000..cfeb3e1f6b41
Binary files /dev/null and b/theme/white/folder.png differ
diff --git a/theme/white/folder.svg b/theme/white/folder.svg
index 003e8b3fb80d..a32ffc8570c2 100644
--- a/theme/white/folder.svg
+++ b/theme/white/folder.svg
@@ -1 +1 @@
-
+
diff --git a/theme/white/folder@2x.png b/theme/white/folder@2x.png
new file mode 100644
index 000000000000..03a919e6c2b1
Binary files /dev/null and b/theme/white/folder@2x.png differ
diff --git a/theme/white/wizard-files.png b/theme/white/wizard-files.png
new file mode 100644
index 000000000000..673a4bde28cb
Binary files /dev/null and b/theme/white/wizard-files.png differ
diff --git a/theme/white/wizard-files.svg b/theme/white/wizard-files.svg
new file mode 100644
index 000000000000..e01fb5b88937
--- /dev/null
+++ b/theme/white/wizard-files.svg
@@ -0,0 +1 @@
+
diff --git a/theme/white/wizard-files@2x.png b/theme/white/wizard-files@2x.png
new file mode 100644
index 000000000000..810030290dee
Binary files /dev/null and b/theme/white/wizard-files@2x.png differ
diff --git a/theme/white/wizard-groupware.png b/theme/white/wizard-groupware.png
new file mode 100644
index 000000000000..e348accb2f34
Binary files /dev/null and b/theme/white/wizard-groupware.png differ
diff --git a/theme/white/wizard-groupware.svg b/theme/white/wizard-groupware.svg
new file mode 100644
index 000000000000..0cd9a33e5469
--- /dev/null
+++ b/theme/white/wizard-groupware.svg
@@ -0,0 +1 @@
+
diff --git a/theme/white/wizard-groupware@2x.png b/theme/white/wizard-groupware@2x.png
new file mode 100644
index 000000000000..ae5024e44249
Binary files /dev/null and b/theme/white/wizard-groupware@2x.png differ
diff --git a/theme/white/wizard-nextcloud.png b/theme/white/wizard-nextcloud.png
new file mode 100644
index 000000000000..8022b79a331a
Binary files /dev/null and b/theme/white/wizard-nextcloud.png differ
diff --git a/theme/white/wizard-nextcloud.svg b/theme/white/wizard-nextcloud.svg
new file mode 100644
index 000000000000..a0330d783f9c
--- /dev/null
+++ b/theme/white/wizard-nextcloud.svg
@@ -0,0 +1,81 @@
+
+
diff --git a/theme/white/wizard-nextcloud@2x.png b/theme/white/wizard-nextcloud@2x.png
new file mode 100644
index 000000000000..ad10827c2b88
Binary files /dev/null and b/theme/white/wizard-nextcloud@2x.png differ
diff --git a/theme/white/wizard-talk.png b/theme/white/wizard-talk.png
new file mode 100644
index 000000000000..fc4646fe0f41
Binary files /dev/null and b/theme/white/wizard-talk.png differ
diff --git a/theme/white/wizard-talk.svg b/theme/white/wizard-talk.svg
new file mode 100644
index 000000000000..45ab71d990f5
--- /dev/null
+++ b/theme/white/wizard-talk.svg
@@ -0,0 +1 @@
+
diff --git a/theme/white/wizard-talk@2x.png b/theme/white/wizard-talk@2x.png
new file mode 100644
index 000000000000..b576ec365970
Binary files /dev/null and b/theme/white/wizard-talk@2x.png differ