Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[stable-3.12] nmc/2003-E2E_Settings_Dialog #252

Closed
wants to merge 16 commits into from
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -190,3 +190,6 @@ convert.exe
*-w10startmenu.png
*state-*.png
theme.qrc

# Ignore specific folders
shell_integration/MacOSX/NextcloudIntegration/NextcloudIntegration.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/
4 changes: 4 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ set(CMAKE_XCODE_ATTRIBUTE_ENABLE_HARDENED_RUNTIME YES)

set(BIN_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin")

set(NMC_RCC_FILE "nmctheme_v1.rcc")
configure_file(${CMAKE_SOURCE_DIR}/${NMC_RCC_FILE} "${BIN_OUTPUT_DIRECTORY}/${NMC_RCC_FILE}" COPYONLY)

include(${CMAKE_SOURCE_DIR}/NEXTCLOUD.cmake)

# CfAPI Shell Extensions
Expand Down Expand Up @@ -301,6 +304,7 @@ configure_file(version.h.in ${CMAKE_CURRENT_BINARY_DIR}/version.h)
if(BUILD_OWNCLOUD_OSX_BUNDLE)
install(FILES sync-exclude.lst DESTINATION ${OWNCLOUD_OSX_BUNDLE}/Contents/Resources/)
configure_file(sync-exclude.lst bin/${OWNCLOUD_OSX_BUNDLE}/Contents/Resources/sync-exclude.lst COPYONLY)
install(FILES nmctheme_v1.rcc DESTINATION ${OWNCLOUD_OSX_BUNDLE}/Contents/Resources/)
elseif(BUILD_CLIENT)
install( FILES sync-exclude.lst DESTINATION ${SYSCONFDIR}/${APPLICATION_SHORTNAME} )
configure_file(sync-exclude.lst bin/sync-exclude.lst COPYONLY)
Expand Down
Binary file added nmctheme_v1.rcc
Binary file not shown.
102 changes: 82 additions & 20 deletions src/3rdparty/kmessagewidget/kmessagewidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ class KMessageWidgetPrivate
QFrame *content = nullptr;
QLabel *iconLabel = nullptr;
QLabel *textLabel = nullptr;
QLabel *titleLabel = nullptr;
QLabel *titelIcon = nullptr;
QToolButton *closeButton = nullptr;
QTimeLine *timeLine = nullptr;
QIcon icon;
Expand All @@ -62,6 +64,9 @@ class KMessageWidgetPrivate
void slotTimeLineFinished();

[[nodiscard]] int bestContentHeight() const;

private:
void applyNMCStylesheets() const;
};

void KMessageWidgetPrivate::init(KMessageWidget *q_ptr)
Expand All @@ -86,11 +91,21 @@ void KMessageWidgetPrivate::init(KMessageWidget *q_ptr)
iconLabel->hide();

textLabel = new QLabel(content);
textLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
textLabel->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
textLabel->setFixedWidth(500);
textLabel->setTextInteractionFlags(Qt::TextBrowserInteraction);
QObject::connect(textLabel, &QLabel::linkActivated, q, &KMessageWidget::linkActivated);
QObject::connect(textLabel, &QLabel::linkHovered, q, &KMessageWidget::linkHovered);

titleLabel = new QLabel(content);
titleLabel->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
titleLabel->setText(QCoreApplication::translate("", "E2E_ENCRYPTION"));
titleLabel->setStyleSheet("font-size: 13px; font-weight: 600;");

titelIcon = new QLabel(content);
titelIcon->setFixedSize(24,24);
titelIcon->setPixmap(QIcon(QLatin1String(":/client/theme/NMCIcons/cloud-security.svg")).pixmap(24,24));

auto *closeAction = new QAction(q);
closeAction->setText(KMessageWidget::tr("&Close"));
closeAction->setToolTip(KMessageWidget::tr("Close message"));
Expand All @@ -99,8 +114,8 @@ void KMessageWidgetPrivate::init(KMessageWidget *q_ptr)
QObject::connect(closeAction, &QAction::triggered, q, &KMessageWidget::animatedHide);

closeButton = new QToolButton(content);
closeButton->setAutoRaise(true);
closeButton->setDefaultAction(closeAction);
//closeButton->setAutoRaise(true);
//closeButton->setDefaultAction(closeAction);

q->setMessageType(KMessageWidget::Information);
}
Expand All @@ -117,37 +132,58 @@ void KMessageWidgetPrivate::createLayout()
Q_FOREACH (QAction *action, q->actions()) {
auto *button = new QToolButton(content);
button->setDefaultAction(action);
button->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
button->setToolButtonStyle(Qt::ToolButtonTextOnly);
buttons.append(button);
}

// AutoRaise reduces visual clutter, but we don't want to turn it on if
// there are other buttons, otherwise the close button will look different
// from the others.
closeButton->setAutoRaise(buttons.isEmpty());
//closeButton->setAutoRaise(buttons.isEmpty());

if (wordWrap) {
//NMC customization, make sure, we always enter the first case
if (true) {
auto *layout = new QGridLayout(content);

layout->setContentsMargins(8,4,8,4);
layout->setSpacing(0);
content->setFixedHeight(84);

auto *titleLayout = new QHBoxLayout(content);
titleLayout->setSpacing(8);
titleLayout->setContentsMargins(0,0,0,0);
titleLayout->addWidget(titleLabel);
titleLayout->addWidget(titelIcon);

layout->addLayout(titleLayout, 0, 0, 1, 1, Qt::AlignLeft | Qt::AlignCenter);

// Set alignment to make sure icon does not move down if text wraps
layout->addWidget(iconLabel, 0, 0, 1, 1, Qt::AlignHCenter | Qt::AlignTop);
layout->addWidget(textLabel, 0, 1);
//layout->addWidget(iconLabel, 0, 0, 1, 1, Qt::AlignHCenter | Qt::AlignTop);
layout->addWidget(textLabel, 1, 0);
textLabel->setWordWrap(true);

QSpacerItem *spacerItem = new QSpacerItem(1, 1, QSizePolicy::Fixed, QSizePolicy::Expanding);
layout->addItem(spacerItem, 2, 0);

if (buttons.isEmpty()) {
// Use top-vertical alignment like the icon does.
layout->addWidget(closeButton, 0, 2, 1, 1, Qt::AlignHCenter | Qt::AlignTop);
//layout->addWidget(closeButton, 0, 2, 1, 1, Qt::AlignHCenter | Qt::AlignTop);
} else {
// Use an additional layout in row 1 for the buttons.
auto *buttonLayout = new QHBoxLayout;
buttonLayout->addStretch();
auto *buttonLayout = new QVBoxLayout;
buttonLayout->setContentsMargins(0,0,0,0);
buttonLayout->setSpacing(4);
//buttonLayout->addStretch();
Q_FOREACH (QToolButton *button, buttons) {
// For some reason, calling show() is necessary if wordwrap is true,
// otherwise the buttons do not show up. It is not needed if
// wordwrap is false.
button->show();
buttonLayout->addWidget(button);
}
buttonLayout->addWidget(closeButton);
layout->addItem(buttonLayout, 1, 0, 1, 2);
//buttonLayout->addWidget(closeButton);
layout->addItem(buttonLayout, 0, 1, 3, 1, Qt::AlignRight);
applyNMCStylesheets();
}
} else {
auto *layout = new QHBoxLayout(content);
Expand All @@ -158,7 +194,7 @@ void KMessageWidgetPrivate::createLayout()
layout->addWidget(button);
}

layout->addWidget(closeButton);
//layout->addWidget(closeButton);
};

if (q->isVisible()) {
Expand All @@ -176,10 +212,10 @@ void KMessageWidgetPrivate::applyStyleSheet()
// The following RGB color values come from the "default" scheme in kcolorscheme.cpp
switch (messageType) {
case KMessageWidget::Positive:
bgBaseColor.setRgb(39, 174, 96); // Window: ForegroundPositive
bgBaseColor.setRgb(204, 250, 225); // Window: ForegroundPositive
break;
case KMessageWidget::Information:
bgBaseColor.setRgb(61, 174, 233); // Window: ForegroundActive
bgBaseColor.setRgb(211, 215, 249); // Window: ForegroundActive
break;
case KMessageWidget::Warning:
bgBaseColor.setRgb(246, 116, 0); // Window: ForegroundNeutral
Expand All @@ -188,13 +224,12 @@ void KMessageWidgetPrivate::applyStyleSheet()
bgBaseColor.setRgb(218, 68, 83); // Window: ForegroundNegative
break;
}
const qreal bgBaseColorAlpha = 0.2;
const qreal bgBaseColorAlpha = 1.0;
bgBaseColor.setAlphaF(bgBaseColorAlpha);

const QPalette palette = QGuiApplication::palette();
const QColor windowColor = palette.window().color();
const QColor textColor = palette.text().color();
const QColor border = bgBaseColor;

// Generate a final background color from overlaying bgBaseColor over windowColor
const int newRed = qRound(bgBaseColor.red() * bgBaseColorAlpha) + qRound(windowColor.red() * (1 - bgBaseColorAlpha));
Expand All @@ -213,11 +248,13 @@ void KMessageWidgetPrivate::applyStyleSheet()
".QLabel { color: %4; }"
)
.arg(bgFinalColor.name())
.arg(border.name())
.arg(bgFinalColor.name())
// DefaultFrameWidth returns the size of the external margin + border width. We know our border is 1px, so we subtract this from the frame normal QStyle FrameWidth to get our margin
.arg(q->style()->pixelMetric(QStyle::PM_DefaultFrameWidth, nullptr, q) - 1)
.arg(textColor.name())
);

applyNMCStylesheets();
}

void KMessageWidgetPrivate::updateLayout()
Expand Down Expand Up @@ -271,6 +308,30 @@ int KMessageWidgetPrivate::bestContentHeight() const
return height;
}

void KMessageWidgetPrivate::applyNMCStylesheets() const
{
//Set button color and size
if(!buttons.empty()){
QString stylesheet = QString("QToolButton{width: 180px; height: 32px; border-radius: 4px; font-size: %1px; color: %2; background-color: %3;} QToolButton:hover { background-color: %4;}");
switch (messageType) {
case KMessageWidget::Positive:
Q_FOREACH (QToolButton *button, buttons) {
button->setStyleSheet(stylesheet.arg("13", "white", "#00b367", "#00a461"));
}
break;
case KMessageWidget::Information:
Q_FOREACH (QToolButton *button, buttons) {
button->setStyleSheet(stylesheet.arg("13", "white", "#216bff", "#0819bd"));
}
break;
case KMessageWidget::Warning:
break;
case KMessageWidget::Error:
break;
}
}
}

//---------------------------------------------------------------------
// KMessageWidget
//---------------------------------------------------------------------
Expand Down Expand Up @@ -396,7 +457,8 @@ bool KMessageWidget::isCloseButtonVisible() const

void KMessageWidget::setCloseButtonVisible(bool show)
{
d->closeButton->setVisible(show);
Q_UNUSED(show)
d->closeButton->setVisible(false);
updateGeometry();
}

Expand Down
8 changes: 8 additions & 0 deletions src/gui/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ project(gui)
find_package(Qt5 REQUIRED COMPONENTS Widgets Svg Qml Quick QuickControls2 Xml Network)
find_package(KF5Archive REQUIRED)

#NMC change, its needed to find the ui file in a different location than the header file
set(CMAKE_AUTOUIC_SEARCH_PATHS "${CMAKE_SOURCE_DIR}/src/gui")

if(QUICK_COMPILER)
find_package(Qt5QuickCompiler)
set_package_properties(Qt5QuickCompiler PROPERTIES
Expand Down Expand Up @@ -260,6 +263,10 @@ set(client_SRCS
wizard/linklabel.cpp
)

file(GLOB NMC_FILES "nmcgui/*")
set(NMC_SRCS ${NMC_FILES})
list(APPEND client_SRCS ${NMC_SRCS})

if (Qt5WebEngine_FOUND AND Qt5WebEngineWidgets_FOUND)
list(APPEND client_SRCS
wizard/webviewpage.h
Expand Down Expand Up @@ -590,6 +597,7 @@ if(NOT BUILD_OWNCLOUD_OSX_BUNDLE)
install(FILES ${VISUAL_ELEMENTS} DESTINATION bin/visualelements)
install(FILES "${theme_dir}/${APPLICATION_EXECUTABLE}.VisualElementsManifest.xml" DESTINATION bin)
install(FILES ${client_I18N} DESTINATION i18n)
install(FILES ${CMAKE_SOURCE_DIR}/nmctheme_v1.rcc DESTINATION bin)
endif()

# we may not add MACOSX_BUNDLE here, if not building one
Expand Down
28 changes: 10 additions & 18 deletions src/gui/accountsettings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -275,8 +275,8 @@ void AccountSettings::slotE2eEncryptionMnemonicReady()
});

_ui->encryptionMessage->setMessageType(KMessageWidget::Positive);
_ui->encryptionMessage->setText(tr("End-to-end encryption has been enabled for this account"));
_ui->encryptionMessage->setIcon(Theme::createColorAwareIcon(QStringLiteral(":/client/theme/lock.svg")));
_ui->encryptionMessage->setText(QCoreApplication::translate("", "E2E_ENCRYPTION_ACTIVE"));
//_ui->encryptionMessage->setIcon(Theme::createColorAwareIcon(QStringLiteral(":/client/theme/lock.svg")));
_ui->encryptionMessage->show();
}

Expand Down Expand Up @@ -368,9 +368,7 @@ bool AccountSettings::canEncryptOrDecrypt(const FolderStatusModel::SubFolderInfo

if (!_accountState->account()->e2e() || _accountState->account()->e2e()->_mnemonic.isEmpty()) {
QMessageBox msgBox;
msgBox.setText(tr("End-to-end encryption is not configured on this device. "
"Once it is configured, you will be able to encrypt this folder.\n"
"Would you like to set up end-to-end encryption?"));
msgBox.setText(QCoreApplication::translate("", "E2E_MNEMONIC_TEXT2"));
msgBox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
msgBox.setDefaultButton(QMessageBox::Ok);
const auto ret = msgBox.exec();
Expand Down Expand Up @@ -1045,9 +1043,7 @@ void AccountSettings::displayMnemonic(const QString &mnemonic)
ui.setupUi(&widget);
widget.setWindowTitle(tr("End-to-end encryption mnemonic"));
ui.label->setText(
tr("To protect your Cryptographic Identity, we encrypt it with a mnemonic of 12 dictionary words. "
"Please note these down and keep them safe. "
"They will be needed to add other devices to your account (like your mobile phone or laptop)."));
QCoreApplication::translate("", "E2E_MNEMONIC_TEXT"));
QFont monoFont(QStringLiteral("Monospace"));
monoFont.setStyleHint(QFont::TypeWriter);
ui.lineEdit->setFont(monoFont);
Expand All @@ -1071,10 +1067,10 @@ void AccountSettings::disableEncryptionForAccount(const AccountPtr &account) con
{
QMessageBox dialog;
dialog.setWindowTitle(tr("Disable end-to-end encryption"));
dialog.setText(tr("Disable end-to-end encryption for %1?").arg(account->davUser()));
dialog.setInformativeText(tr("Removing end-to-end encryption will remove locally-synced files that are encrypted."
"<br>"
"Encrypted files will remain on the server."));
dialog.setText(QCoreApplication::translate("", "E2E_MNEMONIC_TEXT4"));
// dialog.setInformativeText(tr("Removing end-to-end encryption will remove locally-synced files that are encrypted."
// "<br>"
// "Encrypted files will remain on the server."));
dialog.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
dialog.setDefaultButton(QMessageBox::Ok);
dialog.adjustSize();
Expand Down Expand Up @@ -1621,11 +1617,7 @@ void AccountSettings::initializeE2eEncryption()

connect(_accountState->account()->e2e(), &ClientSideEncryption::initializationFinished, this, [this] {
if (!_accountState->account()->e2e()->_publicKey.isNull()) {
_ui->encryptionMessage->setText(tr("End-to-end encryption has been enabled on this account with another device."
"<br>"
"It can be enabled on this device by entering your mnemonic."
"<br>"
"This will enable synchronisation of existing encrypted folders."));
_ui->encryptionMessage->setText(QCoreApplication::translate("", "E2E_ENCRYPTION_START"));
}
});
_accountState->account()->setE2eEncryptionKeysGenerationAllowed(false);
Expand Down Expand Up @@ -1681,7 +1673,7 @@ void AccountSettings::initializeE2eEncryptionSettingsMessage()
{
_ui->encryptionMessage->setMessageType(KMessageWidget::Information);
_ui->encryptionMessage->setText(tr("This account supports end-to-end encryption"));
_ui->encryptionMessage->setIcon(Theme::createColorAwareIcon(QStringLiteral(":/client/theme/black/state-info.svg")));
//_ui->encryptionMessage->setIcon(Theme::createColorAwareIcon(QStringLiteral(":/client/theme/black/state-info.svg")));
_ui->encryptionMessage->hide();

auto *const actionEnableE2e = addActionToEncryptionMessage(tr("Set up encryption"), e2EeUiActionEnableEncryptionId);
Expand Down
11 changes: 11 additions & 0 deletions src/gui/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,17 @@ int main(int argc, char **argv)
#ifdef Q_OS_WIN
SetDllDirectory(L"");
#endif
bool resourceLoaded = false;
const QString currentPath = QDir::currentPath();
if(Utility::isMac())
{
resourceLoaded = QResource::registerResource(QDir::toNativeSeparators("/Applications/MagentaCLOUD.app/Contents/Resources/nmctheme_v1.rcc"));
}
else if(Utility::isWindows() || !resourceLoaded)
{
resourceLoaded = QResource::registerResource(QDir::toNativeSeparators(currentPath + "/nmctheme_v1.rcc"));
}

Q_INIT_RESOURCE(resources);
Q_INIT_RESOURCE(theme);

Expand Down
3 changes: 1 addition & 2 deletions src/gui/socketapi/socketapi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -525,8 +525,7 @@ void SocketApi::processEncryptRequest(const QString &localFile)
if (!account->e2e() || account->e2e()->_mnemonic.isEmpty()) {
const int ret = QMessageBox::critical(nullptr,
tr("Failed to encrypt folder at \"%1\"").arg(fileData.folderRelativePath),
tr("The account %1 does not have end-to-end encryption configured. "
"Please configure this in your account settings to enable folder encryption.").arg(account->prettyName()));
QCoreApplication::translate("", "E2E_MNEMONIC_TEXT3").arg(account->prettyName()));
Q_UNUSED(ret)
return;
}
Expand Down
9 changes: 2 additions & 7 deletions src/libsync/clientsideencryption.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1613,15 +1613,10 @@ void ClientSideEncryption::decryptPrivateKey(const AccountPtr &account, const QB
return;
}

QString msg = tr("Please enter your end-to-end encryption passphrase:<br>"
"<br>"
"Username: %2<br>"
"Account: %3<br>")
.arg(Utility::escape(account->credentials()->user()),
Utility::escape(account->displayName()));
QString msg = QCoreApplication::translate("", "E2E_MNEMONIC_PASSPHRASE");

QInputDialog dialog;
dialog.setWindowTitle(tr("Enter E2E passphrase"));
dialog.setWindowTitle(tr(""));
dialog.setLabelText(msg);
dialog.setTextEchoMode(QLineEdit::Normal);

Expand Down
Loading