From 8a2c3f87dc19e4c88e6a1b1172fb29d3e62ca947 Mon Sep 17 00:00:00 2001 From: Raul Metsma Date: Thu, 16 May 2024 09:27:59 +0300 Subject: [PATCH] Update notification label style IB-7963 Signed-off-by: Raul Metsma --- client/CDoc2.cpp | 6 +- client/CMakeLists.txt | 1 - client/Colors.h | 44 --------------- client/MainWindow.cpp | 37 +++++-------- client/MainWindow.h | 3 +- client/MainWindow_MyEID.cpp | 43 +++++--------- client/dialogs/SettingsDialog.cpp | 9 +-- client/effects/FadeInNotification.cpp | 80 +++++++++++++++++++-------- client/effects/FadeInNotification.h | 17 +++++- client/widgets/LabelButton.cpp | 13 ++++- 10 files changed, 113 insertions(+), 140 deletions(-) delete mode 100644 client/Colors.h diff --git a/client/CDoc2.cpp b/client/CDoc2.cpp index c662088a..f0645e70 100644 --- a/client/CDoc2.cpp +++ b/client/CDoc2.cpp @@ -21,7 +21,6 @@ #include "Application.h" #include "CheckConnection.h" -#include "Colors.h" #include "Crypto.h" #include "QCryptoBackend.h" #include "QSigner.h" @@ -58,9 +57,8 @@ namespace cdoc20 { if(CheckConnection().check()) return true; return dispatchToMain([] { - auto *notification = new FadeInNotification(Application::mainWindow(), - ria::qdigidoc4::colors::WHITE, ria::qdigidoc4::colors::MANTIS); - notification->start(QCoreApplication::translate("MainWindow", "Check internet connection"), 750, 3000, 1200); + FadeInNotification::error(Application::mainWindow()->findChild(QStringLiteral("topBar")), + QCoreApplication::translate("MainWindow", "Check internet connection")); return false; }); } diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index ec54a799..1198afd8 100644 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -43,7 +43,6 @@ add_executable(${PROJECT_NAME} WIN32 MACOSX_BUNDLE CDoc2.h CheckConnection.cpp CheckConnection.h - Colors.h Crypto.cpp Crypto.h CryptoDoc.cpp diff --git a/client/Colors.h b/client/Colors.h deleted file mode 100644 index 46936583..00000000 --- a/client/Colors.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * QDigiDoc4 - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#pragma once - -namespace ria -{ -namespace qdigidoc4 -{ -namespace colors -{ - // Blues - static const QString CURIOUS_BLUE = QStringLiteral("#31A3D9"); - static const QString DEEP_CERULEAN = QStringLiteral("#006EB5"); - // Reds - static const QString MOJO = QStringLiteral("#981E32"); - // Whites - static const QString PORCELAIN = QStringLiteral("#f4f5f6"); - static const QString WHITE = QStringLiteral("#ffffff"); - // Golds-yellows - static const QString MARZIPAN = QStringLiteral("#F8DDA7"); - // Green - static const QString MANTIS = QStringLiteral("#498526"); - // Other - static const QString NONE = QStringLiteral("none"); -} -} -} diff --git a/client/MainWindow.cpp b/client/MainWindow.cpp index 88e4f672..3b59e093 100644 --- a/client/MainWindow.cpp +++ b/client/MainWindow.cpp @@ -22,7 +22,6 @@ #include "Application.h" #include "CheckConnection.h" -#include "Colors.h" #include "CryptoDoc.h" #include "DigiDoc.h" #include "PrintSheet.h" @@ -56,7 +55,7 @@ #include using namespace ria::qdigidoc4; -using namespace ria::qdigidoc4::colors; +using namespace std::chrono; MainWindow::MainWindow( QWidget *parent ) : QWidget( parent ) @@ -457,11 +456,8 @@ void MainWindow::onSignAction(int action, const QString &info1, const QString &i void MainWindow::convertToBDoc() { - if(!wrap(cryptoDoc->fileName(), cryptoDoc->state() == EncryptedContainer)) - return; - - auto *notification = new FadeInNotification(this, WHITE, MANTIS); - notification->start( tr("Converted to signed document!"), 750, 3000, 1200 ); + if(wrap(cryptoDoc->fileName(), cryptoDoc->state() == EncryptedContainer)) + FadeInNotification::success(ui->topBar, tr("Converted to signed document!")); } void MainWindow::convertToCDoc() @@ -488,8 +484,7 @@ void MainWindow::convertToCDoc() ui->cryptoContainerPage->transition(cryptoDoc, qApp->signer()->tokenauth().cert()); selectPage(CryptoDetails); - auto *notification = new FadeInNotification(this, WHITE, MANTIS); - notification->start( tr("Converted to crypto container!"), 750, 3000, 1200 ); + FadeInNotification::success(ui->topBar, tr("Converted to crypto container!")); } void MainWindow::moveCryptoContainer() @@ -523,16 +518,14 @@ void MainWindow::onCryptoAction(int action, const QString &/*id*/, const QString if(decrypt()) { ui->cryptoContainerPage->transition(cryptoDoc, qApp->signer()->tokenauth().cert()); - auto *notification = new FadeInNotification(this, WHITE, MANTIS); - notification->start( tr("Decryption succeeded!"), 750, 3000, 1200 ); + FadeInNotification::success(ui->topBar, tr("Decryption succeeded!")); } break; case EncryptContainer: if(encrypt()) { ui->cryptoContainerPage->transition(cryptoDoc, qApp->signer()->tokenauth().cert()); - auto *notification = new FadeInNotification(this, WHITE, MANTIS); - notification->start( tr("Encryption succeeded!"), 750, 3000, 1200 ); + FadeInNotification::success(ui->topBar, tr("Encryption succeeded!")); } break; case ContainerSaveAs: @@ -823,15 +816,13 @@ void MainWindow::showEvent(QShowEvent * /*event*/) static bool isShown = false; if(isShown) return; - static const int height = 94; - static const int width = 166; - auto *notification = new FadeInNotification(this, WHITE, NONE, - QPoint(this->width() - width - 15, this->height() - height - 70), width, height); + QRect r{{}, QSize{166, 94}}; + r.moveBottomRight(rect().bottomRight() - QPoint{15, 70}); + auto *notification = new FadeInNotification(this, r); notification->setFocusPolicy(Qt::NoFocus); auto *structureFunds = new QSvgWidget(QStringLiteral(":/images/Struktuurifondid.svg"), notification); - structureFunds->resize(width, height); - structureFunds->show(); - notification->start({}, 400, 3000, 1100); + structureFunds->resize(notification->size()); + notification->start(400ms); isShown = true; } @@ -858,8 +849,7 @@ void MainWindow::sign(F &&sign) { if(!CheckConnection().check()) { - auto *notification = new FadeInNotification(this, MOJO, MARZIPAN); - notification->start(tr("Check internet connection"), 750, 3000, 1200); + FadeInNotification::error(ui->topBar, tr("Check internet connection")); return; } @@ -889,8 +879,7 @@ void MainWindow::sign(F &&sign) ui->signContainerPage->transition(digiDoc); - auto *notification = new FadeInNotification(this, WHITE, MANTIS); - notification->start(tr("The container has been successfully signed!"), 750, 3000, 1200); + FadeInNotification::success(ui->topBar, tr("The container has been successfully signed!")); adjustDrops(); } diff --git a/client/MainWindow.h b/client/MainWindow.h index 4bb7a677..0f948576 100644 --- a/client/MainWindow.h +++ b/client/MainWindow.h @@ -95,11 +95,10 @@ private Q_SLOTS: QString selectFile( const QString &title, const QString &filename, bool fixedExt ); void selectPage(ria::qdigidoc4::Pages page); void showCardMenu( bool show ); - void showNotification( const QString &msg, bool isSuccess = false ); template void sign(F &&sign); void updateCardWarnings(const QSmartCardData &data); - bool validateCardError(QSmartCardData::PinType type, QSmartCardData::PinType t, QSmartCard::ErrorType err); + bool validateCardError(QSmartCardData::PinType type, QSmartCardData::PinType src, QSmartCard::ErrorType err); bool validateFiles(const QString &container, const QStringList &files); void showPinBlockedWarning(const QSmartCardData& t); void updateSelector(); diff --git a/client/MainWindow_MyEID.cpp b/client/MainWindow_MyEID.cpp index 558f8dd8..7668feca 100644 --- a/client/MainWindow_MyEID.cpp +++ b/client/MainWindow_MyEID.cpp @@ -64,7 +64,7 @@ void MainWindow::pinUnblock( QSmartCardData::PinType type, bool isForgotPin ) { if( isForgotPin ) text = tr("%1 changed!").arg( QSmartCardData::typeString( type ) ); - showNotification( text, true ); + FadeInNotification::success(ui->topBar, text); QSmartCardData data = qApp->signer()->smartcard()->data(); updateCardWarnings(data); if (type == QSmartCardData::Pin1Type) @@ -84,15 +84,11 @@ void MainWindow::pinUnblock( QSmartCardData::PinType type, bool isForgotPin ) void MainWindow::pinPukChange( QSmartCardData::PinType type ) { - if(validateCardError(type, type, - qApp->signer()->smartcard()->pinChange(type, this))) - { - showNotification( tr("%1 changed!") - .arg( QSmartCardData::typeString( type ) ), true ); - } + if(validateCardError(type, type, qApp->signer()->smartcard()->pinChange(type, this))) + FadeInNotification::success(ui->topBar, tr("%1 changed!").arg(QSmartCardData::typeString(type))); } -bool MainWindow::validateCardError(QSmartCardData::PinType type, QSmartCardData::PinType t, QSmartCard::ErrorType err) +bool MainWindow::validateCardError(QSmartCardData::PinType type, QSmartCardData::PinType src, QSmartCard::ErrorType err) { QSmartCardData data = qApp->signer()->smartcard()->data(); ui->accordion->updateInfo(data); @@ -100,16 +96,10 @@ bool MainWindow::validateCardError(QSmartCardData::PinType type, QSmartCardData: { case QSmartCard::NoError: return true; case QSmartCard::CancelError: -#ifdef Q_OS_WIN - if(!data.isNull() && data.isPinpad()) - if(data.authCert().subjectInfo(QSslCertificate::CountryName) == QStringLiteral("EE")) // only for Estonian ID card - { - showNotification( tr("%1 timeout").arg( QSmartCardData::typeString( type ) ) ); - } -#endif + FadeInNotification::warning(ui->topBar, tr("%1 timeout").arg(QSmartCardData::typeString(type))); break; case QSmartCard::BlockedError: - showNotification( tr("%1 blocked").arg( QSmartCardData::typeString( t ) ) ); + FadeInNotification::warning(ui->topBar, tr("%1 blocked").arg(QSmartCardData::typeString(src))); showPinBlockedWarning(data); selectPage(Pages::MyEid); ui->myEid->warningIcon( @@ -118,33 +108,26 @@ bool MainWindow::validateCardError(QSmartCardData::PinType type, QSmartCardData: data.retryCount(QSmartCardData::PukType) == 0 ); break; case QSmartCard::DifferentError: - showNotification( tr("New %1 codes doesn't match").arg( QSmartCardData::typeString( type ) ) ); + FadeInNotification::warning(ui->topBar, tr("New %1 codes doesn't match").arg(QSmartCardData::typeString(type))); break; case QSmartCard::LenghtError: - showNotification(tr("%1 length has to be between %2 and 12").arg(QSmartCardData::typeString(type)).arg(QSmartCardData::minPinLen(type))); + FadeInNotification::warning(ui->topBar, tr("%1 length has to be between %2 and 12") + .arg(QSmartCardData::typeString(type)).arg(QSmartCardData::minPinLen(type))); break; case QSmartCard::OldNewPinSameError: - showNotification( tr("Old and new %1 has to be different!").arg( QSmartCardData::typeString( type ) ) ); + FadeInNotification::warning(ui->topBar, tr("Old and new %1 has to be different!").arg(QSmartCardData::typeString(type))); break; case QSmartCard::ValidateError: - showNotification( tr("Wrong %1 code. You can try %n more time(s).", nullptr, - data.retryCount(t)).arg( QSmartCardData::typeString(t))); + FadeInNotification::warning(ui->topBar, tr("Wrong %1 code. You can try %n more time(s).", nullptr, + data.retryCount(src)).arg(QSmartCardData::typeString(src))); break; default: - showNotification(tr("Changing %1 failed").arg(QSmartCardData::typeString(type))); + FadeInNotification::warning(ui->topBar, tr("Changing %1 failed").arg(QSmartCardData::typeString(type))); break; } return false; } -void MainWindow::showNotification( const QString &msg, bool isSuccess ) -{ - auto *notification = new FadeInNotification(this, - isSuccess ? QStringLiteral("#ffffff") : QStringLiteral("#353739"), - isSuccess ? QStringLiteral("#498526") : QStringLiteral("#F8DDA7")); - notification->start(msg, 750, 3000, 1200); -} - void MainWindow::showPinBlockedWarning(const QSmartCardData& t) { bool isBlockedPuk = t.retryCount(QSmartCardData::PukType) == 0; diff --git a/client/dialogs/SettingsDialog.cpp b/client/dialogs/SettingsDialog.cpp index 97d417ee..219031d5 100644 --- a/client/dialogs/SettingsDialog.cpp +++ b/client/dialogs/SettingsDialog.cpp @@ -25,7 +25,6 @@ #include "CertStore.h" #endif #include "CheckConnection.h" -#include "Colors.h" #include "Diagnostics.h" #include "FileDialog.h" #include "QSigner.h" @@ -287,22 +286,18 @@ void SettingsDialog::checkConnection() if(CheckConnection connection; !connection.check()) { Application::restoreOverrideCursor(); - auto *notification = new FadeInNotification(this, - ria::qdigidoc4::colors::MOJO, ria::qdigidoc4::colors::MARZIPAN, 0, 120); QString error; QString details = connection.errorDetails(); QTextStream s(&error); s << connection.errorString(); if (!details.isEmpty()) s << "\n\n" << details << "."; - notification->start(error, 750, 3000, 1200); + FadeInNotification::error(this, error, 120); } else { Application::restoreOverrideCursor(); - auto *notification = new FadeInNotification(this, - ria::qdigidoc4::colors::WHITE, ria::qdigidoc4::colors::MANTIS, 0, 120); - notification->start(tr("The connection to certificate status service is successful!"), 750, 3000, 1200); + FadeInNotification::success(this, tr("The connection to certificate status service is successful!")); } } diff --git a/client/effects/FadeInNotification.cpp b/client/effects/FadeInNotification.cpp index 83e3ebe4..176671b4 100644 --- a/client/effects/FadeInNotification.cpp +++ b/client/effects/FadeInNotification.cpp @@ -18,7 +18,6 @@ */ #include "FadeInNotification.h" -#include "Styles.h" #include #include @@ -26,25 +25,39 @@ #include #include -FadeInNotification::FadeInNotification(QWidget *parent, const QString &fgColor, const QString &bgColor, int leftOffset, int height) - : FadeInNotification(parent, fgColor, bgColor, QPoint(leftOffset, 0), parent->width() - leftOffset, height) +using namespace std::chrono; + +constexpr QRect adjustHeight(QRect rect, int height) noexcept { + rect.setHeight(height); + return rect; } -FadeInNotification::FadeInNotification(QWidget *parent, const QString &fgColor, const QString &bgColor, QPoint pos, int width, int height) +FadeInNotification::FadeInNotification(QWidget *parent, QRect rect, Type type, const QString &label) : QLabel(parent) { - setStyleSheet(QStringLiteral("background-color: %2; color: %1;").arg(fgColor, bgColor)); + auto bgcolor = [type] { + switch(type) { + case FadeInNotification::Success: return QStringLiteral("#218123"); + case FadeInNotification::Warning: return QStringLiteral("#FBAE38"); + case FadeInNotification::Error: return QStringLiteral("#AD2A45"); + case FadeInNotification::Default: return QStringLiteral("#2F70B6"); + default: return QStringLiteral("none"); + } + }(); + auto fgcolor = [type] { + return type == FadeInNotification::Warning ? QStringLiteral("#07142A") : QStringLiteral("#FFFFFF"); + }(); + setStyleSheet(QStringLiteral("color: %1; background-color: %2;").arg(fgcolor, bgcolor)); setFocusPolicy(Qt::TabFocus); setAlignment(Qt::AlignHCenter | Qt::AlignVCenter); - QFont font = Styles::font(Styles::Condensed, 22); - font.setPixelSize(22); - setFont(font); - setMinimumSize(width, height); + QFont f(QStringLiteral("Roboto")); + f.setPixelSize(22); + setFont(f); setGraphicsEffect(new QGraphicsOpacityEffect(this)); - move(pos); - if(QPoint c = parent->geometry().center(); pos.x() > c.x() && pos.y() > c.y()) - parent->installEventFilter(this); + setGeometry(rect); + setText(label); + parent->installEventFilter(this); } bool FadeInNotification::eventFilter(QObject *watched, QEvent *event) @@ -53,29 +66,37 @@ bool FadeInNotification::eventFilter(QObject *watched, QEvent *event) { if(auto *resize = static_cast(event)) { - QSize newPos = resize->size() - resize->oldSize(); - move(pos() + QPoint(newPos.width(), newPos.height())); + QRect rect = geometry(); + if(QSize s = resize->oldSize() / 2; rect.x() > s.width() && rect.y() > s.height()) + { + QSize newPos = resize->size() - resize->oldSize(); + move(pos() + QPoint(newPos.width(), newPos.height())); + } + else + { + rect.setWidth(parentWidget()->width()); + setGeometry(rect); + } } } return QLabel::eventFilter(watched, event); } -void FadeInNotification::start( const QString &label, int fadeInTime, int displayTime, int fadeOutTime ) +void FadeInNotification::start(ms fadeInTime) { - setText(label); auto *a = new QPropertyAnimation(graphicsEffect(), "opacity", this); - a->setDuration(fadeInTime); + a->setDuration(int(fadeInTime.count())); a->setStartValue(0); - a->setEndValue(0.95); + a->setEndValue(1); a->setEasingCurve(QEasingCurve::InBack); a->start(QPropertyAnimation::DeleteWhenStopped); - connect(a, &QPropertyAnimation::finished, this, [this, displayTime, fadeOutTime] { + connect(a, &QPropertyAnimation::finished, this, [this] { if(focusPolicy() == Qt::TabFocus) setFocus(); - QTimer::singleShot(displayTime, this, [this, fadeOutTime] { + QTimer::singleShot(3s, this, [this] { auto *a = new QPropertyAnimation(graphicsEffect(), "opacity", this); - a->setDuration(fadeOutTime); - a->setStartValue(0.95); + a->setDuration(int((1200ms).count())); + a->setStartValue(1); a->setEndValue(0); a->setEasingCurve(QEasingCurve::OutBack); a->start(QPropertyAnimation::DeleteWhenStopped); @@ -84,3 +105,18 @@ void FadeInNotification::start( const QString &label, int fadeInTime, int displa }); show(); } + +void FadeInNotification::success(QWidget *parent, const QString &label) +{ + (new FadeInNotification(parent, adjustHeight(parent->rect(), 65), FadeInNotification::Success, label))->start(); +} + +void FadeInNotification::warning(QWidget *parent, const QString &label) +{ + (new FadeInNotification(parent, adjustHeight(parent->rect(), 65), FadeInNotification::Warning, label))->start(); +} + +void FadeInNotification::error(QWidget *parent, const QString &label, int height) +{ + (new FadeInNotification(parent, adjustHeight(parent->rect(), height), FadeInNotification::Error, label))->start(); +} diff --git a/client/effects/FadeInNotification.h b/client/effects/FadeInNotification.h index dd0ab1a1..10a504ee 100644 --- a/client/effects/FadeInNotification.h +++ b/client/effects/FadeInNotification.h @@ -27,9 +27,20 @@ class FadeInNotification final: public QLabel Q_OBJECT public: - explicit FadeInNotification(QWidget *parent, const QString &fgColor, const QString &bgColor, int leftOffset = 92, int height = 65); - explicit FadeInNotification(QWidget *parent, const QString &fgColor, const QString &bgColor, QPoint pos, int width, int height); - void start(const QString &label, int fadeInTime, int displayTime, int fadeOutTime); + using ms = std::chrono::milliseconds; + enum Type { + Success, + Warning, + Error, + Default, + None, + }; + explicit FadeInNotification(QWidget *parent, QRect rect, Type type = None, const QString &label = {}); + void start(ms fadeInTime = ms(750)); + + static void success(QWidget *parent, const QString &label); + static void warning(QWidget *parent, const QString &label); + static void error(QWidget *parent, const QString &label, int height = 65); private: bool eventFilter(QObject *watched, QEvent *event) final; diff --git a/client/widgets/LabelButton.cpp b/client/widgets/LabelButton.cpp index 72d9cd29..03fc6698 100644 --- a/client/widgets/LabelButton.cpp +++ b/client/widgets/LabelButton.cpp @@ -18,13 +18,10 @@ */ #include "LabelButton.h" -#include "Colors.h" #include "Styles.h" #include -using namespace ria::qdigidoc4::colors; - LabelButton::LabelButton( QWidget *parent ): QToolButton(parent) {} @@ -34,6 +31,16 @@ void LabelButton::init(Style style, const QString &label) setFont(Styles::font(Styles::Condensed, 12)); if(!label.isEmpty()) setAccessibleName(label.toLower()); + + // Blues + static const QString CURIOUS_BLUE = QStringLiteral("#31A3D9"); + static const QString DEEP_CERULEAN = QStringLiteral("#006EB5"); + // Reds + static const QString MOJO = QStringLiteral("#981E32"); + // Whites + static const QString PORCELAIN = QStringLiteral("#f4f5f6"); + static const QString WHITE = QStringLiteral("#ffffff"); + static const QString borderRadius = QStringLiteral(" border-radius: 2px;"); static const QString none = QStringLiteral("none"); static const QString solid = QStringLiteral("1px solid %1");