From 4222ad1a2b044ca80c5a7e1e5f6c6767e29a330f Mon Sep 17 00:00:00 2001 From: VGolovchenko <v.golovchenko3@gmail.com> Date: Sat, 11 Jul 2020 20:02:59 +0300 Subject: [PATCH] add CertificateManager page and logic add svg icon --- CellFrameDashboard.pro | 2 + .../CellFrameDashboardGUI.pro | 6 +- .../DapServiceController.cpp | 10 + CellFrameDashboardGUI/DapServiceController.h | 8 +- CellFrameDashboardGUI/main.cpp | 20 ++ CellFrameDashboardGUI/qml.qrc | 34 ++ .../icons/Certificates/btn_actions.svg | 16 + .../icons/Certificates/btn_actions_hover.svg | 16 + .../Certificates/btn_actions_no-active.svg | 6 + .../icons/Certificates/btn_create_done.svg | 16 + .../Certificates/btn_create_done_hover.svg | 16 + .../btn_create_done_no-active.svg | 6 + .../Certificates/cellframe-logo-dashboard.svg | 13 + .../icons/Certificates/close_icon.svg | 4 + .../icons/Certificates/close_icon_hover.svg | 4 + .../icons/Certificates/ic_arrow_up.svg | 6 + .../resources/icons/Certificates/ic_info.svg | 6 + .../icons/Certificates/ic_search.svg | 5 + .../icons/Certificates/icon_arrow_down.svg | 6 + .../icons/Certificates/icon_certificates.svg | 23 ++ .../Certificates/icon_certificates_hover.svg | 23 ++ .../icons/Certificates/radio_off_dark.svg | 4 + .../icons/Certificates/radio_on_dark.svg | 4 + .../screen/DapMainApplicationWindow.qml | 32 +- .../Certificates/CertificateInfoItem.qml | 79 +++++ .../CertificatesActionsButtonList.qml | 232 +++++++++++++ .../Certificates/CertificatesListView.qml | 169 +++++++++ .../Certificates/CertificatesLogic.qml | 288 ++++++++++++++++ .../CertificatesMainPage.qml.autosave | 23 ++ .../Certificates/CertificatesModels.qml | 198 +++++++++++ .../Certificates/CreateCertificateItem.qml | 232 +++++++++++++ .../Certificates/CreateFinishedItem.qml | 92 +++++ .../Certificates/DapCertificatesMainPage.qml | 320 ++++++++++++++++++ .../desktop/Certificates/HeaderItem.qml | 58 ++++ .../Certificates/models/FindDelegateModel.qml | 73 ++++ .../Certificates/parts/CloseButton.qml | 22 ++ .../parts/CreateCertificateModel.qml | 15 + .../Certificates/parts/FindDelegateModel.qml | 73 ++++ .../desktop/Certificates/parts/InputField.qml | 78 +++++ .../parts/PlaceholderTextView.qml.autosave | 13 + .../Certificates/parts/SearchInputBox.qml | 103 ++++++ .../Certificates/parts/TextInputFilter.qml | 70 ++++ .../Certificates/parts/TitleTextView.qml | 39 +++ .../desktop/Certificates/parts/ToolButton.qml | 39 +++ .../desktop/Certificates/parts/Utils.qml | 72 ++++ .../DapInputNewWalletNameRightPanel.qml | 4 +- .../CellFrameDashboardService.pro | 8 + .../DapServiceController.cpp | 3 + .../DapServiceController.h | 2 + 49 files changed, 2587 insertions(+), 4 deletions(-) create mode 100644 CellFrameDashboardGUI/resources/icons/Certificates/btn_actions.svg create mode 100644 CellFrameDashboardGUI/resources/icons/Certificates/btn_actions_hover.svg create mode 100644 CellFrameDashboardGUI/resources/icons/Certificates/btn_actions_no-active.svg create mode 100644 CellFrameDashboardGUI/resources/icons/Certificates/btn_create_done.svg create mode 100644 CellFrameDashboardGUI/resources/icons/Certificates/btn_create_done_hover.svg create mode 100644 CellFrameDashboardGUI/resources/icons/Certificates/btn_create_done_no-active.svg create mode 100644 CellFrameDashboardGUI/resources/icons/Certificates/cellframe-logo-dashboard.svg create mode 100644 CellFrameDashboardGUI/resources/icons/Certificates/close_icon.svg create mode 100644 CellFrameDashboardGUI/resources/icons/Certificates/close_icon_hover.svg create mode 100644 CellFrameDashboardGUI/resources/icons/Certificates/ic_arrow_up.svg create mode 100644 CellFrameDashboardGUI/resources/icons/Certificates/ic_info.svg create mode 100644 CellFrameDashboardGUI/resources/icons/Certificates/ic_search.svg create mode 100644 CellFrameDashboardGUI/resources/icons/Certificates/icon_arrow_down.svg create mode 100644 CellFrameDashboardGUI/resources/icons/Certificates/icon_certificates.svg create mode 100644 CellFrameDashboardGUI/resources/icons/Certificates/icon_certificates_hover.svg create mode 100644 CellFrameDashboardGUI/resources/icons/Certificates/radio_off_dark.svg create mode 100644 CellFrameDashboardGUI/resources/icons/Certificates/radio_on_dark.svg create mode 100644 CellFrameDashboardGUI/screen/desktop/Certificates/CertificateInfoItem.qml create mode 100644 CellFrameDashboardGUI/screen/desktop/Certificates/CertificatesActionsButtonList.qml create mode 100644 CellFrameDashboardGUI/screen/desktop/Certificates/CertificatesListView.qml create mode 100644 CellFrameDashboardGUI/screen/desktop/Certificates/CertificatesLogic.qml create mode 100644 CellFrameDashboardGUI/screen/desktop/Certificates/CertificatesMainPage.qml.autosave create mode 100644 CellFrameDashboardGUI/screen/desktop/Certificates/CertificatesModels.qml create mode 100644 CellFrameDashboardGUI/screen/desktop/Certificates/CreateCertificateItem.qml create mode 100644 CellFrameDashboardGUI/screen/desktop/Certificates/CreateFinishedItem.qml create mode 100644 CellFrameDashboardGUI/screen/desktop/Certificates/DapCertificatesMainPage.qml create mode 100644 CellFrameDashboardGUI/screen/desktop/Certificates/HeaderItem.qml create mode 100644 CellFrameDashboardGUI/screen/desktop/Certificates/models/FindDelegateModel.qml create mode 100644 CellFrameDashboardGUI/screen/desktop/Certificates/parts/CloseButton.qml create mode 100644 CellFrameDashboardGUI/screen/desktop/Certificates/parts/CreateCertificateModel.qml create mode 100644 CellFrameDashboardGUI/screen/desktop/Certificates/parts/FindDelegateModel.qml create mode 100644 CellFrameDashboardGUI/screen/desktop/Certificates/parts/InputField.qml create mode 100644 CellFrameDashboardGUI/screen/desktop/Certificates/parts/PlaceholderTextView.qml.autosave create mode 100644 CellFrameDashboardGUI/screen/desktop/Certificates/parts/SearchInputBox.qml create mode 100644 CellFrameDashboardGUI/screen/desktop/Certificates/parts/TextInputFilter.qml create mode 100644 CellFrameDashboardGUI/screen/desktop/Certificates/parts/TitleTextView.qml create mode 100644 CellFrameDashboardGUI/screen/desktop/Certificates/parts/ToolButton.qml create mode 100644 CellFrameDashboardGUI/screen/desktop/Certificates/parts/Utils.qml diff --git a/CellFrameDashboard.pro b/CellFrameDashboard.pro index 14df6c1..d235244 100755 --- a/CellFrameDashboard.pro +++ b/CellFrameDashboard.pro @@ -1,6 +1,8 @@ TEMPLATE = subdirs SUBDIRS = CellFrameDashboardGUI CellFrameDashboardService + + CellFrameDashboardGUI.subdir = CellFrameDashboardGUI CellFrameDashboardService.subdir = CellFrameDashboardService CellFrameDashboardGUI.depends = CellFrameDashboardService diff --git a/CellFrameDashboardGUI/CellFrameDashboardGUI.pro b/CellFrameDashboardGUI/CellFrameDashboardGUI.pro index ba3fa42..ff564e4 100755 --- a/CellFrameDashboardGUI/CellFrameDashboardGUI.pro +++ b/CellFrameDashboardGUI/CellFrameDashboardGUI.pro @@ -1,8 +1,9 @@ -QT += qml quick widgets +QT += qml quick widgets svg TEMPLATE = app CONFIG += c++11 +LIBS += -ldl !defined(BRAND,var){ # Default brand @@ -18,11 +19,14 @@ VER_PAT = 3 win32 { VERSION = $${VER_MAJ}.$${VER_MIN}.$$VER_PAT DEFINES += CLI_PATH=\\\"cellframe-node-cli.exe\\\" + DEFINES += TOOLS_PATH=\\\"cellframe-node-tool.exe\\\" DEFINES += HAVE_STRNDUP } else { VERSION = $$VER_MAJ\.$$VER_MIN\-$$VER_PAT DEFINES += CLI_PATH=\\\"/opt/cellframe-node/bin/cellframe-node-cli\\\" + DEFINES += TOOLS_PATH=\\\"/opt/cellframe-node/bin/cellframe-node-tool\\\" + DEFINES += CONFIG_PATH=\\\"/opt/cellframe-node/bin/cellframe-node-cli\\\" } # The following define makes your compiler emit warnings if you use diff --git a/CellFrameDashboardGUI/DapServiceController.cpp b/CellFrameDashboardGUI/DapServiceController.cpp index d85a1c6..e34ecde 100644 --- a/CellFrameDashboardGUI/DapServiceController.cpp +++ b/CellFrameDashboardGUI/DapServiceController.cpp @@ -79,7 +79,10 @@ void DapServiceController::requestToService(const QString &asServiceName, const const QVariant &arg5, const QVariant &arg6, const QVariant &arg7, const QVariant &arg8, const QVariant &arg9, const QVariant &arg10) { + DapAbstractCommand * transceiver = dynamic_cast<DapAbstractCommand*>(m_DAPRpcSocket->findService(asServiceName)); +// qDebug() << "DapServiceController::requestToService, asServiceName:" << asServiceName << arg1 << arg2 << arg3 << arg4 << arg5 +// << "transceiver:" << transceiver; Q_ASSERT(transceiver); disconnect(transceiver, SIGNAL(serviceResponded(QVariant)), this, SLOT(findEmittedSignal(QVariant))); connect(transceiver, SIGNAL(serviceResponded(QVariant)), SLOT(findEmittedSignal(QVariant))); @@ -95,6 +98,7 @@ void DapServiceController::notifyService(const QString &asServiceName, const QVa const QVariant &arg5, const QVariant &arg6, const QVariant &arg7, const QVariant &arg8, const QVariant &arg9, const QVariant &arg10) { + qDebug() << "DapServiceController::notifyService" << asServiceName << arg1 << arg2 << arg3 << arg4 << arg5; DapAbstractCommand * transceiver = dynamic_cast<DapAbstractCommand*>(m_DAPRpcSocket->findService(asServiceName)); Q_ASSERT(transceiver); @@ -105,6 +109,11 @@ void DapServiceController::notifyService(const QString &asServiceName, const QVa /// Register command. void DapServiceController::registerCommand() { + + m_transceivers.append(qMakePair(dynamic_cast<DapAbstractCommand*>(m_DAPRpcSocket->addService( + new DapCertificateManagerCommands(DapCertificateCommands::serviceName(), m_DAPRpcSocket))) + , QString("certificateManagerOperationResult"))); + // Application shutdown team m_transceivers.append(qMakePair(dynamic_cast<DapAbstractCommand*>(m_DAPRpcSocket->addService(new DapQuitApplicationCommand("DapQuitApplicationCommand", m_DAPRpcSocket))), QString())); // GUI client activation command in case it is minimized/expanded @@ -187,6 +196,7 @@ void DapServiceController::registerCommand() void DapServiceController::findEmittedSignal(const QVariant &aValue) { DapAbstractCommand * transceiver = dynamic_cast<DapAbstractCommand *>(sender()); + //qDebug() << "findEmittedSignal, transceiver:" << transceiver << ", value:" << aValue; Q_ASSERT(transceiver); auto service = std::find_if(m_transceivers.begin(), m_transceivers.end(), [=] (const QPair<DapAbstractCommand*, QString>& it) { diff --git a/CellFrameDashboardGUI/DapServiceController.h b/CellFrameDashboardGUI/DapServiceController.h index 93efd97..babc97c 100644 --- a/CellFrameDashboardGUI/DapServiceController.h +++ b/CellFrameDashboardGUI/DapServiceController.h @@ -14,6 +14,7 @@ #include "handlers/DapAbstractCommand.h" #include "handlers/DapQuitApplicationCommand.h" #include "handlers/DapActivateClientCommand.h" +#include "handlers/DapCertificateManagerCommands.h" #include "handlers/DapUpdateLogsCommand.h" #include "handlers/DapAddWalletCommand.h" #include "handlers/DapGetWalletsInfoCommand.h" @@ -29,6 +30,8 @@ #include "handlers/DapGetHistoryExecutedCmdCommand.h" #include "handlers/DapSaveHistoryExecutedCmdCommand.h" + + class DapServiceController : public QObject { Q_OBJECT @@ -81,7 +84,7 @@ public: /// Application version. Q_PROPERTY(QString Version MEMBER m_sVersion READ getVersion NOTIFY versionChanged) - Q_PROPERTY(QString CurrentNetwork MEMBER m_sVersion READ getCurrentNetwork WRITE setCurrentNetwork NOTIFY currentNetworkChanged) + Q_PROPERTY(QString CurrentNetwork MEMBER m_sCurrentNetwork READ getCurrentNetwork WRITE setCurrentNetwork NOTIFY currentNetworkChanged) Q_PROPERTY(int IndexCurrentNetwork MEMBER m_iIndexCurrentNetwork READ getIndexCurrentNetwork WRITE setIndexCurrentNetwork NOTIFY indexCurrentNetworkChanged) @@ -154,6 +157,9 @@ signals: /// The signal is emitted when receiving a history of commands executed by the cli handler. /// @param aHistory History of commands executed by cli handler. void historyExecutedCmdReceived(const QVariant& aHistory); + + //Ñоблюдаем оригинальную типизацию в Ñигналах, Ñ…Ð¾Ñ‚Ñ Ñ‚ÑƒÑ‚ лучше MapVariantList или что-то подобное + void certificateManagerOperationResult(const QVariant& result); private slots: /// Register command. diff --git a/CellFrameDashboardGUI/main.cpp b/CellFrameDashboardGUI/main.cpp index a004129..8aec284 100644 --- a/CellFrameDashboardGUI/main.cpp +++ b/CellFrameDashboardGUI/main.cpp @@ -53,11 +53,31 @@ int main(int argc, char *argv[]) DapServiceController &controller = DapServiceController::getInstance(); controller.init(&dapServiceClient); dapServiceClient.init(); + + + //register only enums + qmlRegisterUncreatableType<DapCertificateType>("DapCertificateManager.Commands", 1, 0, "DapCertificateType" + , "Error create DapCertificateType"); + + //register enums and constant property as singletone + qmlRegisterSingletonType<DapCertificateCommands>("DapCertificateManager.Commands", 1, 0, "DapCertificateCommands" + , [](QQmlEngine *engine, QJSEngine *scriptEngine) -> QObject * { + Q_UNUSED(engine) + Q_UNUSED(scriptEngine) + + //qInfo() << "DapCertificateCommands initialize in Qml"; + QQmlEngine::setObjectOwnership(DapCertificateCommands::instance() + , QQmlEngine::ObjectOwnership::CppOwnership); + return DapCertificateCommands::instance(); + }); + + qmlRegisterType<DapLogMessage>("Demlabs", 1, 0, "DapLogMessage"); qmlRegisterType<DapWallet>("Demlabs", 1, 0, "DapWallet"); qmlRegisterType<DapWalletToken>("Demlabs", 1, 0, "DapWalletToken"); qRegisterMetaType<DapWallet>(); qRegisterMetaType<DapWalletToken>(); + QQmlApplicationEngine engine; engine.rootContext()->setContextProperty("dapServiceController", &DapServiceController::getInstance()); engine.rootContext()->setContextProperty("pt", 1); diff --git a/CellFrameDashboardGUI/qml.qrc b/CellFrameDashboardGUI/qml.qrc index 2458100..398196c 100755 --- a/CellFrameDashboardGUI/qml.qrc +++ b/CellFrameDashboardGUI/qml.qrc @@ -149,5 +149,39 @@ <file>resources/icons/next_year_icon.png</file> <file>resources/icons/previous_month_icon.png</file> <file>resources/icons/previous_year_icon.png</file> + <file>screen/desktop/Certificates/DapCertificatesMainPage.qml</file> + <file>screen/desktop/Certificates/HeaderItem.qml</file> + <file>resources/icons/Certificates/btn_actions.svg</file> + <file>resources/icons/Certificates/btn_actions_hover.svg</file> + <file>resources/icons/Certificates/btn_actions_no-active.svg</file> + <file>resources/icons/Certificates/btn_create_done.svg</file> + <file>resources/icons/Certificates/btn_create_done_hover.svg</file> + <file>resources/icons/Certificates/btn_create_done_no-active.svg</file> + <file>resources/icons/Certificates/cellframe-logo-dashboard.svg</file> + <file>resources/icons/Certificates/close_icon.svg</file> + <file>resources/icons/Certificates/close_icon_hover.svg</file> + <file>resources/icons/Certificates/ic_arrow_up.svg</file> + <file>resources/icons/Certificates/ic_info.svg</file> + <file>resources/icons/Certificates/icon_arrow_down.svg</file> + <file>resources/icons/Certificates/icon_certificates.svg</file> + <file>resources/icons/Certificates/icon_certificates_hover.svg</file> + <file>resources/icons/Certificates/ic_search.svg</file> + <file>resources/icons/Certificates/radio_off_dark.svg</file> + <file>resources/icons/Certificates/radio_on_dark.svg</file> + <file>screen/desktop/Certificates/parts/SearchInputBox.qml</file> + <file>screen/desktop/Certificates/CertificatesModels.qml</file> + <file>screen/desktop/Certificates/CertificatesListView.qml</file> + <file>screen/desktop/Certificates/CertificatesActionsButtonList.qml</file> + <file>screen/desktop/Certificates/parts/TextInputFilter.qml</file> + <file>screen/desktop/Certificates/CreateCertificateItem.qml</file> + <file>screen/desktop/Certificates/CertificateInfoItem.qml</file> + <file>screen/desktop/Certificates/CreateFinishedItem.qml</file> + <file>screen/desktop/Certificates/parts/ToolButton.qml</file> + <file>screen/desktop/Certificates/parts/CloseButton.qml</file> + <file>screen/desktop/Certificates/parts/InputField.qml</file> + <file>screen/desktop/Certificates/models/FindDelegateModel.qml</file> + <file>screen/desktop/Certificates/CertificatesLogic.qml</file> + <file>screen/desktop/Certificates/parts/TitleTextView.qml</file> + <file>screen/desktop/Certificates/parts/Utils.qml</file> </qresource> </RCC> diff --git a/CellFrameDashboardGUI/resources/icons/Certificates/btn_actions.svg b/CellFrameDashboardGUI/resources/icons/Certificates/btn_actions.svg new file mode 100644 index 0000000..7b6142b --- /dev/null +++ b/CellFrameDashboardGUI/resources/icons/Certificates/btn_actions.svg @@ -0,0 +1,16 @@ +<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="353" height="39" viewBox="0 0 353 39"> + <defs> + <filter id="bg" x="0" y="0" width="353" height="39" filterUnits="userSpaceOnUse"> + <feOffset dy="1" input="SourceAlpha"/> + <feGaussianBlur stdDeviation="0.5" result="blur"/> + <feFlood flood-color="#010143" flood-opacity="0.2"/> + <feComposite operator="in" in2="blur"/> + <feComposite in="SourceGraphic"/> + </filter> + </defs> + <g id="btn_actions" transform="translate(1.5 0.5)"> + <g transform="matrix(1, 0, 0, 1, -1.5, -0.5)" filter="url(#bg)"> + <rect id="bg-2" data-name="bg" width="350" height="36" rx="4" transform="translate(1.5 0.5)" fill="#271c4e"/> + </g> + </g> +</svg> diff --git a/CellFrameDashboardGUI/resources/icons/Certificates/btn_actions_hover.svg b/CellFrameDashboardGUI/resources/icons/Certificates/btn_actions_hover.svg new file mode 100644 index 0000000..be1332a --- /dev/null +++ b/CellFrameDashboardGUI/resources/icons/Certificates/btn_actions_hover.svg @@ -0,0 +1,16 @@ +<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="353" height="39" viewBox="0 0 353 39"> + <defs> + <filter id="bg" x="0" y="0" width="353" height="39" filterUnits="userSpaceOnUse"> + <feOffset dy="1" input="SourceAlpha"/> + <feGaussianBlur stdDeviation="0.5" result="blur"/> + <feFlood flood-color="#43011a" flood-opacity="0.2"/> + <feComposite operator="in" in2="blur"/> + <feComposite in="SourceGraphic"/> + </filter> + </defs> + <g id="btn_actions_hover" transform="translate(1.5 0.5)"> + <g transform="matrix(1, 0, 0, 1, -1.5, -0.5)" filter="url(#bg)"> + <rect id="bg-2" data-name="bg" width="350" height="36" rx="4" transform="translate(1.5 0.5)" fill="#d51f5d"/> + </g> + </g> +</svg> diff --git a/CellFrameDashboardGUI/resources/icons/Certificates/btn_actions_no-active.svg b/CellFrameDashboardGUI/resources/icons/Certificates/btn_actions_no-active.svg new file mode 100644 index 0000000..9752e06 --- /dev/null +++ b/CellFrameDashboardGUI/resources/icons/Certificates/btn_actions_no-active.svg @@ -0,0 +1,6 @@ +<svg id="btn_actions_no-active" xmlns="http://www.w3.org/2000/svg" width="350" height="36" viewBox="0 0 350 36"> + <g id="bg" fill="none" stroke="#211a3a" stroke-width="1"> + <rect width="350" height="36" rx="4" stroke="none"/> + <rect x="0.5" y="0.5" width="349" height="35" rx="3.5" fill="none"/> + </g> +</svg> diff --git a/CellFrameDashboardGUI/resources/icons/Certificates/btn_create_done.svg b/CellFrameDashboardGUI/resources/icons/Certificates/btn_create_done.svg new file mode 100644 index 0000000..87d426b --- /dev/null +++ b/CellFrameDashboardGUI/resources/icons/Certificates/btn_create_done.svg @@ -0,0 +1,16 @@ +<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="135" height="39" viewBox="0 0 135 39"> + <defs> + <filter id="bg_send_btn" x="0" y="0" width="135" height="39" filterUnits="userSpaceOnUse"> + <feOffset dy="1" input="SourceAlpha"/> + <feGaussianBlur stdDeviation="0.5" result="blur"/> + <feFlood flood-color="#010143" flood-opacity="0.2"/> + <feComposite operator="in" in2="blur"/> + <feComposite in="SourceGraphic"/> + </filter> + </defs> + <g id="btn_create_done" transform="translate(1.5 0.5)"> + <g transform="matrix(1, 0, 0, 1, -1.5, -0.5)" filter="url(#bg_send_btn)"> + <rect id="bg_send_btn-2" data-name="bg_send_btn" width="132" height="36" rx="4" transform="translate(1.5 0.5)" fill="#271c4e"/> + </g> + </g> +</svg> diff --git a/CellFrameDashboardGUI/resources/icons/Certificates/btn_create_done_hover.svg b/CellFrameDashboardGUI/resources/icons/Certificates/btn_create_done_hover.svg new file mode 100644 index 0000000..fa66cc6 --- /dev/null +++ b/CellFrameDashboardGUI/resources/icons/Certificates/btn_create_done_hover.svg @@ -0,0 +1,16 @@ +<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="135" height="39" viewBox="0 0 135 39"> + <defs> + <filter id="bg_send_btn" x="0" y="0" width="135" height="39" filterUnits="userSpaceOnUse"> + <feOffset dy="1" input="SourceAlpha"/> + <feGaussianBlur stdDeviation="0.5" result="blur"/> + <feFlood flood-color="#43011a" flood-opacity="0.2"/> + <feComposite operator="in" in2="blur"/> + <feComposite in="SourceGraphic"/> + </filter> + </defs> + <g id="btn_create_done_hover" transform="translate(1.5 0.5)"> + <g transform="matrix(1, 0, 0, 1, -1.5, -0.5)" filter="url(#bg_send_btn)"> + <rect id="bg_send_btn-2" data-name="bg_send_btn" width="132" height="36" rx="4" transform="translate(1.5 0.5)" fill="#d51f5d"/> + </g> + </g> +</svg> diff --git a/CellFrameDashboardGUI/resources/icons/Certificates/btn_create_done_no-active.svg b/CellFrameDashboardGUI/resources/icons/Certificates/btn_create_done_no-active.svg new file mode 100644 index 0000000..5af57f3 --- /dev/null +++ b/CellFrameDashboardGUI/resources/icons/Certificates/btn_create_done_no-active.svg @@ -0,0 +1,6 @@ +<svg id="btn_create_done_no-active" xmlns="http://www.w3.org/2000/svg" width="132" height="36" viewBox="0 0 132 36"> + <g id="bg_send_btn" fill="none" stroke="#3e3853" stroke-width="1"> + <rect width="132" height="36" rx="4" stroke="none"/> + <rect x="0.5" y="0.5" width="131" height="35" rx="3.5" fill="none"/> + </g> +</svg> diff --git a/CellFrameDashboardGUI/resources/icons/Certificates/cellframe-logo-dashboard.svg b/CellFrameDashboardGUI/resources/icons/Certificates/cellframe-logo-dashboard.svg new file mode 100644 index 0000000..20df02e --- /dev/null +++ b/CellFrameDashboardGUI/resources/icons/Certificates/cellframe-logo-dashboard.svg @@ -0,0 +1,13 @@ +<svg id="cellframe-logo-dashboard" xmlns="http://www.w3.org/2000/svg" width="111" height="24" viewBox="0 0 111 24"> + <g id="Слой6"> + <path id="Path_1417" data-name="Path 1417" d="M1154.829,228.311c-.117.2-.024.515.646.4a18.624,18.624,0,0,1,4.8-.217,13.765,13.765,0,0,1,3.538.851c.552.18,1.149.458,1.4.362s.229-.475-.031-.858a4.857,4.857,0,0,0-1.613-1.381,7.563,7.563,0,0,0-3.711-.914,8.975,8.975,0,0,0-3.715.825A3.206,3.206,0,0,0,1154.829,228.311Z" transform="translate(-1148.635 -226.547)" fill="#fff" fill-rule="evenodd"/> + <g id="Group_2119" data-name="Group 2119" transform="translate(17.602 24) rotate(-178.904)"> + <path id="Path_1418" data-name="Path 1418" d="M.043,1.76c-.117.2-.023.515.646.4a18.618,18.618,0,0,1,4.8-.213A13.781,13.781,0,0,1,9.023,2.8c.552.181,1.149.459,1.4.363s.228-.475-.031-.858A4.87,4.87,0,0,0,8.778.919,7.572,7.572,0,0,0,5.066,0,8.968,8.968,0,0,0,1.351.823,3.2,3.2,0,0,0,.043,1.76Z" transform="translate(0 0)" fill="#fff" fill-rule="evenodd"/> + </g> + <path id="Path_1419" data-name="Path 1419" d="M179.177,549.52a10.834,10.834,0,0,1,3.707.794c2.762,1.127,4.571,3.065,5.121,2.914.422-.116.328-1.378.064-2.315-.418-1.481-.882-1.753-.7-1.947.235-.248,1.622.684,3.015,2.579a11.7,11.7,0,0,1,2.2,6.275,9.048,9.048,0,0,1-2.876,7.24,11,11,0,0,1-4.544,2.522,9.221,9.221,0,0,1-4.278.267,12.906,12.906,0,0,1-5.741-2.327c-.968-.65-1.693-1.451-2.054-1.142-.392.336-.215,1.519.171,2.609.3.844.783,1.458.46,1.56-.479.151-2.49-1.755-3.681-3.831A10.562,10.562,0,0,1,168.6,559a10.167,10.167,0,0,1,.257-2.1,8.871,8.871,0,0,1,1.612-3.45,10.422,10.422,0,0,1,3.355-2.74A10.186,10.186,0,0,1,179.177,549.52Zm.563.5a9.915,9.915,0,0,0-4.558.687,9.122,9.122,0,0,0-3.3,2.1,8.707,8.707,0,0,0-2.128,3.16,9.876,9.876,0,0,0-.239,5.7,7.726,7.726,0,0,0,1.634,3.32c.93,1.079.46-3.509,1.768-2.554.771.562,1.9,2.31,4.332,3.639a9.783,9.783,0,0,0,6.8,1.294,11.456,11.456,0,0,0,5.011-2.448,7.981,7.981,0,0,0,2.555-3.705,9.119,9.119,0,0,0,.408-3.566c-.312-2.934-1.931-5.7-2.337-5.333-.36.321-.189,3.433-1.186,2.917a20.36,20.36,0,0,1-2.389-2.157,16.951,16.951,0,0,0-2.362-1.729A8.667,8.667,0,0,0,179.74,550.018Z" transform="translate(-168.598 -546.827)" fill="#fff" fill-rule="evenodd"/> + <g id="Group_2120" data-name="Group 2120" transform="translate(1.079 3.813)"> + <path id="Path_1420" data-name="Path 1420" d="M387.68,550.9a9.564,9.564,0,0,1,3.474.748,8.714,8.714,0,0,1,3.85,3.066c1.278,1.789,1.705,3.825,2.466,3.554a3.675,3.675,0,0,0,1.48-1.483c.484-.825.967-.4,1.167.758a7.3,7.3,0,0,1-.3,3.472,8.165,8.165,0,0,1-2.192,3.576,8.705,8.705,0,0,1-3.49,2.057,9.94,9.94,0,0,1-4.653.3,9.409,9.409,0,0,1-5.48-3.12,10.327,10.327,0,0,1-1.4-1.964,11.7,11.7,0,0,0-1.049-1.685c-.429-.435-.755-.5-1.354.231-.324.4-.723,1.592-1.3.943a3.624,3.624,0,0,1-.477-1.928,8.5,8.5,0,0,1,1.441-4.61,9.439,9.439,0,0,1,3.086-2.789A8.91,8.91,0,0,1,387.68,550.9Zm.174.516a7.77,7.77,0,0,0-4.177.844,8,8,0,0,0-3.483,3.349,5.062,5.062,0,0,0-.674,2.844c.133.515,1.745-1.75,2.486-.917.59.664.408,1.609,1.109,3.247a8.727,8.727,0,0,0,8.075,5.581,7.759,7.759,0,0,0,3.476-.606,7.9,7.9,0,0,0,2.632-1.767,6.493,6.493,0,0,0,1.64-2.593c.378-1,.528-2.06-.05-1.928-.724.166-1.346,1.161-1.947,1.2-.648.039-.718-.935-1.135-2.315a11.821,11.821,0,0,0-1.088-2.6,8.024,8.024,0,0,0-6.864-4.34Z" transform="translate(-378.418 -550.902)" fill="#fff" fill-rule="evenodd"/> + </g> + </g> + <path id="Path_1429" data-name="Path 1429" d="M19.7-173.34a4.735,4.735,0,0,1-1.885-.365,4.01,4.01,0,0,1-1.46-1.064,4.88,4.88,0,0,1-.942-1.724,7.594,7.594,0,0,1-.333-2.347,6.8,6.8,0,0,1,.376-2.347,5.151,5.151,0,0,1,1.013-1.724,4.278,4.278,0,0,1,1.488-1.064,4.554,4.554,0,0,1,1.814-.365,6.022,6.022,0,0,1,1.1.091,6.341,6.341,0,0,1,.85.213,3.907,3.907,0,0,1,.588.243,3.275,3.275,0,0,1,.312.182l-.4,1.215a2.143,2.143,0,0,0-.368-.2q-.241-.106-.546-.213a4.638,4.638,0,0,0-.666-.175,3.918,3.918,0,0,0-.73-.068,3.3,3.3,0,0,0-1.4.289,2.923,2.923,0,0,0-1.063.836,3.862,3.862,0,0,0-.673,1.329,6.121,6.121,0,0,0-.234,1.755,6.693,6.693,0,0,0,.206,1.717,3.876,3.876,0,0,0,.617,1.329,2.806,2.806,0,0,0,1.028.858,3.217,3.217,0,0,0,1.439.3,4.941,4.941,0,0,0,1.573-.213,6.641,6.641,0,0,0,.935-.38l.354,1.215a1.942,1.942,0,0,1-.354.19,4.635,4.635,0,0,1-.638.22,7.492,7.492,0,0,1-.893.182A7.522,7.522,0,0,1,19.7-173.34Zm4.564-.228V-184.1h6v1.261h-4.62v3.13h4.11v1.231h-4.11v3.646h4.975v1.261Zm14-1.276v1.276h-5.91V-184.1h1.375v9.253Zm7.356,0v1.276h-5.91V-184.1h1.375v9.253Zm1.446,1.276V-184.1h5.924v1.261H48.442v3.175h4.039v1.246H48.442v4.847Zm12.415-4.406q.227.3.574.8t.716,1.094q.368.6.73,1.253a13.053,13.053,0,0,1,.617,1.261h-1.5q-.283-.577-.617-1.17t-.673-1.132q-.34-.539-.673-1.01t-.6-.82q-.184.015-.376.015H56.053v4.117H54.678v-10.377a7.272,7.272,0,0,1,1.3-.205q.716-.053,1.311-.053a5.091,5.091,0,0,1,3.153.836,2.95,2.95,0,0,1,1.084,2.492,3.063,3.063,0,0,1-.517,1.793A3.053,3.053,0,0,1,59.483-177.974ZM57.4-182.912q-.879,0-1.346.046v3.965h.978a9.672,9.672,0,0,0,1.276-.076,2.753,2.753,0,0,0,.957-.289,1.484,1.484,0,0,0,.6-.6,2.13,2.13,0,0,0,.213-1.026,2.066,2.066,0,0,0-.213-.988,1.639,1.639,0,0,0-.574-.623,2.4,2.4,0,0,0-.85-.319A5.681,5.681,0,0,0,57.4-182.912Zm13.152,9.344q-.241-.684-.454-1.345t-.439-1.345h-4.45l-.893,2.689H62.884q.567-1.671,1.063-3.092t.971-2.7q.475-1.276.942-2.438t.978-2.3H68.1q.51,1.14.978,2.3t.942,2.438q.475,1.276.971,2.7t1.063,3.092Zm-1.29-3.9q-.454-1.322-.9-2.56t-.928-2.378q-.5,1.139-.942,2.378t-.886,2.56Zm8.532,2.446q-.142-.365-.376-.927t-.5-1.215q-.269-.653-.574-1.345t-.574-1.307q-.269-.615-.5-1.1t-.376-.744q-.156,1.793-.255,3.882t-.17,4.216H73.117q.057-1.367.128-2.758t.163-2.735q.092-1.345.2-2.621t.234-2.416h1.2q.383.669.822,1.58t.879,1.907q.439,1,.85,1.99t.751,1.816q.34-.82.751-1.816t.85-1.99q.439-1,.879-1.907t.822-1.58h1.2q.482,5.09.723,10.529H82.23q-.071-2.127-.17-4.216t-.255-3.882q-.142.258-.376.744t-.5,1.1q-.269.615-.574,1.307t-.574,1.345q-.269.653-.5,1.215t-.376.927Zm7.937,1.459V-184.1h6v1.261h-4.62v3.13h4.11v1.231h-4.11v3.646H92.08v1.261Z" transform="translate(18.92 190.34)" fill="#fff"/> +</svg> diff --git a/CellFrameDashboardGUI/resources/icons/Certificates/close_icon.svg b/CellFrameDashboardGUI/resources/icons/Certificates/close_icon.svg new file mode 100644 index 0000000..3328bb5 --- /dev/null +++ b/CellFrameDashboardGUI/resources/icons/Certificates/close_icon.svg @@ -0,0 +1,4 @@ +<svg id="close_icon" xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"> + <rect id="bg_close_icon" width="20" height="20" fill="none"/> + <path id="close_object_icon" d="M23.442,23l4.467-4.467a.312.312,0,0,0-.442-.442L23,22.558l-4.467-4.467a.312.312,0,1,0-.442.442L22.558,23l-4.467,4.467a.312.312,0,1,0,.442.442L23,23.442l4.467,4.467a.312.312,0,0,0,.442-.442Z" transform="translate(-12.5 -12.5)" fill="#070023"/> +</svg> diff --git a/CellFrameDashboardGUI/resources/icons/Certificates/close_icon_hover.svg b/CellFrameDashboardGUI/resources/icons/Certificates/close_icon_hover.svg new file mode 100644 index 0000000..615605b --- /dev/null +++ b/CellFrameDashboardGUI/resources/icons/Certificates/close_icon_hover.svg @@ -0,0 +1,4 @@ +<svg id="close_icon_hover" xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"> + <rect id="bg_close_icon" width="20" height="20" fill="none"/> + <path id="close_object_icon" d="M23.442,23l4.467-4.467a.312.312,0,0,0-.442-.442L23,22.558l-4.467-4.467a.312.312,0,1,0-.442.442L22.558,23l-4.467,4.467a.312.312,0,1,0,.442.442L23,23.442l4.467,4.467a.312.312,0,0,0,.442-.442Z" transform="translate(-12.5 -12.5)" fill="#d51f5d"/> +</svg> diff --git a/CellFrameDashboardGUI/resources/icons/Certificates/ic_arrow_up.svg b/CellFrameDashboardGUI/resources/icons/Certificates/ic_arrow_up.svg new file mode 100644 index 0000000..d3f9b62 --- /dev/null +++ b/CellFrameDashboardGUI/resources/icons/Certificates/ic_arrow_up.svg @@ -0,0 +1,6 @@ +<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"> + <g id="ic_arrow_up" transform="translate(24.105 24) rotate(180)"> + <path id="path" d="M0,0,5,5l5-5Z" transform="translate(7.285 10)" fill="#070023"/> + <rect id="rectangle" width="24" height="24" transform="translate(0.105)" fill="none"/> + </g> +</svg> diff --git a/CellFrameDashboardGUI/resources/icons/Certificates/ic_info.svg b/CellFrameDashboardGUI/resources/icons/Certificates/ic_info.svg new file mode 100644 index 0000000..fa1e407 --- /dev/null +++ b/CellFrameDashboardGUI/resources/icons/Certificates/ic_info.svg @@ -0,0 +1,6 @@ +<svg xmlns="http://www.w3.org/2000/svg" width="30" height="30" viewBox="0 0 30 30"> + <g id="ic_info" transform="translate(-7)"> + <rect id="Rectangle_1604" data-name="Rectangle 1604" width="30" height="30" transform="translate(7)" fill="none"/> + <path id="Path_1931" data-name="Path 1931" d="M15,5A10,10,0,1,0,25,15,10,10,0,0,0,15,5Zm0,18.222A8.222,8.222,0,1,1,23.222,15,8.222,8.222,0,0,1,15,23.222ZM13.889,9.444A1.111,1.111,0,1,1,15,10.556,1.111,1.111,0,0,1,13.889,9.444Zm3.556,10.081v.585a.445.445,0,0,1-.445.445H13a.445.445,0,0,1-.445-.445v-.585a.445.445,0,0,1,.31-.424l.915-.29a.154.154,0,0,0,.108-.147V14.111h-.7A.635.635,0,0,1,13,12.871l2.533-.8a.445.445,0,0,1,.579.424v6.169a.154.154,0,0,0,.108.147l.915.29a.445.445,0,0,1,.31.424Z" transform="translate(7)" fill="#d51f5d"/> + </g> +</svg> diff --git a/CellFrameDashboardGUI/resources/icons/Certificates/ic_search.svg b/CellFrameDashboardGUI/resources/icons/Certificates/ic_search.svg new file mode 100644 index 0000000..77bb363 --- /dev/null +++ b/CellFrameDashboardGUI/resources/icons/Certificates/ic_search.svg @@ -0,0 +1,5 @@ +<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"> + <g id="ic_search" transform="translate(-12.67 -12.17)"> + <path id="Path_1930" data-name="Path 1930" d="M5.419,0a5.419,5.419,0,0,1,.4,10.824V17.05a.4.4,0,0,1-.793,0V10.824A5.419,5.419,0,0,1,5.419,0Zm0,.793a4.626,4.626,0,1,0,4.626,4.626A4.626,4.626,0,0,0,5.419.793Z" transform="translate(12.67 19.833) rotate(-45)" fill="#fff" fill-rule="evenodd"/> + </g> +</svg> diff --git a/CellFrameDashboardGUI/resources/icons/Certificates/icon_arrow_down.svg b/CellFrameDashboardGUI/resources/icons/Certificates/icon_arrow_down.svg new file mode 100644 index 0000000..b1f9aec --- /dev/null +++ b/CellFrameDashboardGUI/resources/icons/Certificates/icon_arrow_down.svg @@ -0,0 +1,6 @@ +<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"> + <g id="icon_arrow_down" transform="translate(24 24) rotate(180)"> + <rect id="bg_arrow_down_icon" width="24" height="24" fill="none"/> + <path id="arrow_down_object_icon" d="M0,5,5,0l5,5Z" transform="translate(7 9)" fill="#505559"/> + </g> +</svg> diff --git a/CellFrameDashboardGUI/resources/icons/Certificates/icon_certificates.svg b/CellFrameDashboardGUI/resources/icons/Certificates/icon_certificates.svg new file mode 100644 index 0000000..45c5129 --- /dev/null +++ b/CellFrameDashboardGUI/resources/icons/Certificates/icon_certificates.svg @@ -0,0 +1,23 @@ +<svg xmlns="http://www.w3.org/2000/svg" width="19" height="18" viewBox="0 0 19 18"> + <g id="icon_certificates" transform="translate(-29 -117)"> + <rect id="bg_icon" width="18" height="18" transform="translate(29 117)" fill="none"/> + <g id="Group_2131" data-name="Group 2131" transform="translate(-358 -237)"> + <g id="Rectangle_1534" data-name="Rectangle 1534" transform="translate(387 354)" fill="#211a3a" stroke="#fff" stroke-width="1"> + <rect width="15" height="18" rx="1" stroke="none"/> + <rect x="0.5" y="0.5" width="14" height="17" rx="0.5" fill="none"/> + </g> + <g id="Group_2346" data-name="Group 2346" transform="translate(0 -1.511)"> + <path id="Path_1435" data-name="Path 1435" d="M-1663.591-801.045l-.158,6.847,2.057-2.2,1.819,2.2v-6.847Z" transform="translate(2063.168 1165.243)" fill="#211a3a" stroke="#fff" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/> + <g id="Ellipse_5" data-name="Ellipse 5" transform="translate(397 357.511)" fill="#211a3a" stroke="#fff" stroke-width="1"> + <circle cx="4.5" cy="4.5" r="4.5" stroke="none"/> + <circle cx="4.5" cy="4.5" r="4" fill="none"/> + </g> + </g> + <g id="Group_2131-2" data-name="Group 2131"> + <line id="Line_38" data-name="Line 38" x2="5.478" transform="translate(390.022 358.5)" fill="none" stroke="#fff" stroke-linecap="round" stroke-width="1"/> + <line id="Line_39" data-name="Line 39" x2="6.478" transform="translate(390.022 367.5)" fill="none" stroke="#fff" stroke-linecap="round" stroke-width="1"/> + <path id="Path_1436" data-name="Path 1436" d="M0,0H5.709" transform="translate(390.022 362.5)" fill="none" stroke="#fff" stroke-linecap="round" stroke-width="1"/> + </g> + </g> + </g> +</svg> diff --git a/CellFrameDashboardGUI/resources/icons/Certificates/icon_certificates_hover.svg b/CellFrameDashboardGUI/resources/icons/Certificates/icon_certificates_hover.svg new file mode 100644 index 0000000..5bf19cd --- /dev/null +++ b/CellFrameDashboardGUI/resources/icons/Certificates/icon_certificates_hover.svg @@ -0,0 +1,23 @@ +<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 18 18"> + <g id="icon_certificates_hover" transform="translate(-29 -117)"> + <rect id="bg_icon" width="18" height="18" transform="translate(29 117)" fill="none"/> + <g id="Group_2131" data-name="Group 2131" transform="translate(-358 -237)"> + <g id="Rectangle_1534" data-name="Rectangle 1534" transform="translate(387 354)" fill="#fff" stroke="#fff" stroke-width="1"> + <rect width="15" height="18" rx="1" stroke="none"/> + <rect x="0.5" y="0.5" width="14" height="17" rx="0.5" fill="none"/> + </g> + <g id="Group_2346" data-name="Group 2346" transform="translate(0 0.989)"> + <path id="Path_1435" data-name="Path 1435" d="M-1663.62-801.045l-.129,5.582,1.677-1.793,1.483,1.793v-5.582Z" transform="translate(2062.721 1164.008)" fill="#fff" stroke="#d51f5d" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/> + </g> + <g id="Group_2131-2" data-name="Group 2131"> + <line id="Line_38" data-name="Line 38" x2="5.478" transform="translate(390.022 358.5)" fill="none" stroke="#d51f5d" stroke-linecap="round" stroke-width="1"/> + <line id="Line_39" data-name="Line 39" x2="6.478" transform="translate(390.022 367.5)" fill="none" stroke="#d51f5d" stroke-linecap="round" stroke-width="1"/> + <path id="Path_1436" data-name="Path 1436" d="M0,0H5.709" transform="translate(390.022 362.5)" fill="none" stroke="#d51f5d" stroke-linecap="round" stroke-width="1"/> + </g> + <g id="Ellipse_6" data-name="Ellipse 6" transform="translate(397 358)" fill="#fff" stroke="#d51f5d" stroke-width="1"> + <circle cx="4" cy="4" r="4" stroke="none"/> + <circle cx="4" cy="4" r="3.5" fill="none"/> + </g> + </g> + </g> +</svg> diff --git a/CellFrameDashboardGUI/resources/icons/Certificates/radio_off_dark.svg b/CellFrameDashboardGUI/resources/icons/Certificates/radio_off_dark.svg new file mode 100644 index 0000000..c7ed55d --- /dev/null +++ b/CellFrameDashboardGUI/resources/icons/Certificates/radio_off_dark.svg @@ -0,0 +1,4 @@ +<svg id="radio_off_dark" xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"> + <rect id="rectangle" width="20" height="20" fill="none"/> + <path id="radio_off" d="M10.333,2a8.333,8.333,0,1,0,8.333,8.333A8.358,8.358,0,0,0,10.333,2Zm0,15A6.667,6.667,0,1,1,17,10.333,6.686,6.686,0,0,1,10.333,17Z" transform="translate(-0.333 -0.333)" fill="#211a3a" fill-rule="evenodd"/> +</svg> diff --git a/CellFrameDashboardGUI/resources/icons/Certificates/radio_on_dark.svg b/CellFrameDashboardGUI/resources/icons/Certificates/radio_on_dark.svg new file mode 100644 index 0000000..ed2664a --- /dev/null +++ b/CellFrameDashboardGUI/resources/icons/Certificates/radio_on_dark.svg @@ -0,0 +1,4 @@ +<svg id="radio_on_dark" xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"> + <rect id="radio_on" width="20" height="20" fill="none"/> + <path id="radio_on-2" data-name="radio_on" d="M10.333,6.167A4.167,4.167,0,1,0,14.5,10.333a4.126,4.126,0,0,0-4.167-4.167Zm0-4.167a8.333,8.333,0,1,0,8.333,8.333A8.358,8.358,0,0,0,10.333,2Zm0,15A6.667,6.667,0,1,1,17,10.333,6.686,6.686,0,0,1,10.333,17Z" transform="translate(-0.333 -0.333)" fill="#211a3a" fill-rule="evenodd"/> +</svg> diff --git a/CellFrameDashboardGUI/screen/DapMainApplicationWindow.qml b/CellFrameDashboardGUI/screen/DapMainApplicationWindow.qml index 39d4952..830b1e9 100644 --- a/CellFrameDashboardGUI/screen/DapMainApplicationWindow.qml +++ b/CellFrameDashboardGUI/screen/DapMainApplicationWindow.qml @@ -1,5 +1,7 @@ import QtQuick 2.4 import "qrc:/resources/QML" +import "qrc:/screen/desktop/Certificates" + DapMainApplicationWindowForm { @@ -17,13 +19,29 @@ DapMainApplicationWindowForm ///@detalis Path to the console tab. readonly property string consoleScreen: "qrc:/screen/" + device + "/Console/DapConsoleTab.qml" + ///@detalis Path to the console tab. + readonly property string certificatesScreen: "qrc:/screen/" + device + "/Certificates/DapCertificatesMainPage.qml" + ///@details dapMainFonts Project font loader readonly property QtObject dapMainFonts: DapFontRoboto {} + //readonly property DapFontQuicksand quicksandFonts: + DapFontQuicksand { + id: quicksandFonts + } + + property var dapWallets: [] signal modelWalletsUpdated() + + //open in module visible root context, only for work + Component{ + DapCertificatesMainPage { } + } + + ListModel { id: dapNetworkModel @@ -62,6 +80,15 @@ DapMainApplicationWindowForm hoverIcon: "qrc:/resources/icons/icon_history_hover.png" }) + + append ({ + name: qsTr("Certificates"), + page: certificatesScreen, + normalIcon: "qrc:/resources/icons/Certificates/icon_certificates.svg", + hoverIcon: "qrc:/resources/icons/Certificates/icon_certificates_hover.svg" + }) + + append ({ name: qsTr("Console"), page: consoleScreen, @@ -103,10 +130,13 @@ DapMainApplicationWindowForm target: dapServiceController onNetworksListReceived: { + if (!networkList) + console.error("networkList is empty") + for(var n=0; n < Object.keys(networkList).length; ++n) { dapServiceController.CurrentNetwork = networkList[0]; - dapServiceController.IndexCurrentNetwork = 0; + dapServiceController.IndexCurrentNetwork = 0; //тут разве не должно быть n? или Ñтой Ñтроки вообще недолжно быть тут. РеÑли ÑпиÑок Ñетей пуÑÑ‚? dapNetworkModel.append({name: networkList[n]}) } } diff --git a/CellFrameDashboardGUI/screen/desktop/Certificates/CertificateInfoItem.qml b/CellFrameDashboardGUI/screen/desktop/Certificates/CertificateInfoItem.qml new file mode 100644 index 0000000..b6324b0 --- /dev/null +++ b/CellFrameDashboardGUI/screen/desktop/Certificates/CertificateInfoItem.qml @@ -0,0 +1,79 @@ +import QtQuick 2.9 +import "qrc:/widgets" +import "parts" + + + + +Rectangle { + id: root + property alias closeButton: closeButton + property alias certificateDataListView: certificateDataListView + + implicitWidth: 100 + implicitHeight: 200 + + border.color: "#E2E1E6" + border.width: 1 * pt + radius: 8 * pt + color: "transparent" + + //part animation on created and open + visible: false + opacity: visible ? 1.0 : 0.0 + Behavior on opacity { + NumberAnimation { + duration: 100 + easing.type: Easing.InOutQuad + } + } + + + Item { + id: titleRectangle + width: parent.width + height: 40 * pt + + CloseButton { + id: closeButton + x: 16 * pt + } // + + + Text { + id: certificatesTitleText + anchors{ + left: closeButton.right + leftMargin: 18 * pt + verticalCenter: closeButton.verticalCenter + } + font: quicksandFonts.bold14 + color: "#3E3853" + text: qsTr("Info about certificate") + } + } //titleRectangle + + + ListView { + id: certificateDataListView + y: titleRectangle.y + titleRectangle.height + 26 * pt + width: parent.width + height: contentHeight + spacing: 22 * pt + clip: true + + delegate: TitleTextView { + x: 20 * pt + title.text: model.keyView + content.text: model.value + } + } + + + + + +} //root + + + diff --git a/CellFrameDashboardGUI/screen/desktop/Certificates/CertificatesActionsButtonList.qml b/CellFrameDashboardGUI/screen/desktop/Certificates/CertificatesActionsButtonList.qml new file mode 100644 index 0000000..a267d84 --- /dev/null +++ b/CellFrameDashboardGUI/screen/desktop/Certificates/CertificatesActionsButtonList.qml @@ -0,0 +1,232 @@ +import QtQuick 2.9 +import QtQuick.Layouts 1.2 +import QtQuick.Controls 2.2 +import "qrc:/widgets" + + + + +Item { + id: root + + signal selectedAccessKeyType(int index) + + property alias certificateAccessTypeRepeater: certificateAccessTypeRepeater + + property alias createCertificateButton: createCertificateButton + property alias importCertificateButton: importCertificateButton + property alias exportPublicCertificateToFileButton: exportPublicCertificateToFileButton + property alias exportPublicCertificateToMempoolButton: exportPublicCertificateToMempoolButton + property alias addSignatureToCertificateButton: addSignatureToCertificateButton + property alias deleteCertificateButton: deleteCertificateButton + + property bool certificateSelected: false + property bool bothAccessTypeCertificateSelected: false + + implicitWidth: 270 * pt + implicitHeight: 166 * pt + + //part animation on created and open + visible: false + opacity: visible ? 1.0 : 0.0 + Behavior on opacity { + NumberAnimation { + duration: 100 + easing.type: Easing.InOutQuad + } + } + + function setAccessTypeSeletedIndex(index) { + //TODO выделÑÑ‚ÑŒ нужную кнопку + } + + + ButtonGroup { + id: buttonGroup + } + + + Item { + id: radioButtonFrame + y: 12 * pt + width: parent.width - x + height: 166 * pt + + Text { + id: filterTitleText + x: 15 * pt + font: quicksandFonts.bold14 + color: "#3E3853" + text: qsTr("Filter") + } + + ColumnLayout { + id: certificateAccessTypeLayout + spacing: 35 * pt + y: filterTitleText.y + filterTitleText.height + 24 * pt + x: 15 * pt + width: parent.width - x + + Repeater { + id: certificateAccessTypeRepeater + + DapRadioButton { //qrc:/screen/desktop/Certificates/CertificatesActionsButtonList.qml:73:17: QML DapRadioButtonForm.ui: Binding loop detected for property "baselineOffset" + id: buttonSelectionNothing + nameRadioButton: model.name + Layout.preferredHeight: 16 * pt + Layout.fillWidth: true + indicatorSize: 16 * pt + indicatorInnerSize: 7 * pt + spaceIndicatorText: 18 * pt + fontRadioButton: quicksandFonts.regular16 + indicatorBackgroundColor: "transparent" + indicatorBorder.width: 2 * pt + indicatorBorderColor: "#211A3A" + indicatorInnerColorActiv: "#211A3A" + indicatorInnerColorNormal: "transparent" + nameTextColor: "#070023" + ButtonGroup.group: buttonGroup + checked: model.selected + onClicked: { + root.selectedAccessKeyType(model.index) + } + } // + } // + } // + } //radioButtonFrame + + + Text { + id: actionsTitleText + x: 15 * pt + y: radioButtonFrame.y + radioButtonFrame.height + 44 * pt + font: quicksandFonts.bold14 + color: "#3E3853" + text: qsTr("Actions") + } + + + ColumnLayout { + id: actionButtonsLayout + spacing: 24 * pt + y: actionsTitleText.y + actionsTitleText.height + 24 * pt + width: parent.width + + DapButton { + id: createCertificateButton + textButton: qsTr("Create certificate") + Layout.fillWidth: true + Layout.preferredHeight: 36 * pt + + colorBackgroundNormal: "#271C4E" + colorBackgroundHover: "#D2145D" + colorButtonTextNormal: "#FFFFFF" + colorButtonTextHover: "#FFFFFF" + borderColorButton: "#000000" + borderWidthButton: 0 + radius: 4 * pt + fontButton: quicksandFonts.regular16 + horizontalAligmentText: Qt.AlignHCenter + } + + DapButton { + id: importCertificateButton + textButton: qsTr("Import certificate") + Layout.fillWidth: true + Layout.preferredHeight: 36 * pt + visible: false //TODO need clarification of the requirements + + colorBackgroundNormal: "#271C4E" + colorBackgroundHover: "#D2145D" + colorButtonTextNormal: "#FFFFFF" + colorButtonTextHover: "#FFFFFF" + borderColorButton: "#000000" + borderWidthButton: 0 + radius: 4 * pt + fontButton: quicksandFonts.regular16 + horizontalAligmentText: Qt.AlignHCenter + } + + + DapButton { + id: exportPublicCertificateToFileButton + textButton: qsTr("Export public certificate to file") + Layout.fillWidth: true + Layout.preferredHeight: 36 * pt + + enabled: root.certificateSelected && bothAccessTypeCertificateSelected + colorBackgroundNormal: enabled ? "#271C4E" : "white" + colorBackgroundHover: enabled ? "#D2145D" : "white" + colorButtonTextNormal: enabled ? "#FFFFFF" : "#211A3A" + colorButtonTextHover: enabled ? "#FFFFFF" : "#211A3A" + borderColorButton: enabled ? "#000000" : "#211A3A" + borderWidthButton: enabled ? 0 : (1 * pt) + radius: 4 * pt + fontButton: quicksandFonts.regular16 + horizontalAligmentText: Qt.AlignHCenter + } + + + DapButton { + id: exportPublicCertificateToMempoolButton + textButton: qsTr("Export public certificate to mempool") + Layout.fillWidth: true + Layout.preferredHeight: 36 * pt + + enabled: root.certificateSelected + colorBackgroundNormal: enabled ? "#271C4E" : "white" + colorBackgroundHover: enabled ? "#D2145D" : "white" + colorButtonTextNormal: enabled ? "#FFFFFF" : "#211A3A" + colorButtonTextHover: enabled ? "#FFFFFF" : "#211A3A" + borderColorButton: enabled ? "#000000" : "#211A3A" + borderWidthButton: enabled ? 0 : (1 * pt) + radius: 4 * pt + fontButton: quicksandFonts.regular16 + horizontalAligmentText: Qt.AlignHCenter + } + + + DapButton { + id: addSignatureToCertificateButton + textButton: qsTr("Add signature to certificate") + Layout.fillWidth: true + Layout.preferredHeight: 36 * pt + visible: false //TODO need clarification of the requirements + + enabled: root.certificateSelected + colorBackgroundNormal: enabled ? "#271C4E" : "white" + colorBackgroundHover: enabled ? "#D2145D" : "white" + colorButtonTextNormal: enabled ? "#FFFFFF" : "#211A3A" + colorButtonTextHover: enabled ? "#FFFFFF" : "#211A3A" + borderColorButton: enabled ? "#000000" : "#211A3A" + borderWidthButton: enabled ? 0 : (1 * pt) + radius: 4 * pt + fontButton: quicksandFonts.regular16 + horizontalAligmentText: Qt.AlignHCenter + } + + DapButton { + id: deleteCertificateButton + textButton: qsTr("Delete certificate") + Layout.fillWidth: true + Layout.preferredHeight: 36 * pt + + enabled: root.certificateSelected + colorBackgroundNormal: enabled ? "#271C4E" : "white" + colorBackgroundHover: enabled ? "#D2145D" : "white" + colorButtonTextNormal: enabled ? "#FFFFFF" : "#211A3A" + colorButtonTextHover: enabled ? "#FFFFFF" : "#211A3A" + borderColorButton: enabled ? "#000000" : "#211A3A" + borderWidthButton: enabled ? 0 : (1 * pt) + radius: 4 * pt + fontButton: quicksandFonts.regular16 + horizontalAligmentText: Qt.AlignHCenter + } + + + } //actionButtonsLayout + + + + +} //root diff --git a/CellFrameDashboardGUI/screen/desktop/Certificates/CertificatesListView.qml b/CellFrameDashboardGUI/screen/desktop/Certificates/CertificatesListView.qml new file mode 100644 index 0000000..74df2d9 --- /dev/null +++ b/CellFrameDashboardGUI/screen/desktop/Certificates/CertificatesListView.qml @@ -0,0 +1,169 @@ +import QtQuick 2.9 +import "parts" + + + +ListView { + id: root + property alias delegateComponent: delegateComponent + signal selectedIndex(int index) + signal infoClicked(int index) + + property string seletedCertificateAccessType: qsTr("Public") + property bool infoTitleTextVisible: false + + + //interactive: contentHeight > height + headerPositioning: ListView.OverlayHeader + spacing: 14 * pt + clip: true + + + header: Item { + width: parent.width + height: certificatesTitle.height + tableTitle.height + spacing + z: 10 + + Rectangle { + id: certificatesTitle + width: parent.width + height: 40 * pt + + Text { + id: certificatesTitleText + x: 15 * pt + height: parent.height + verticalAlignment: Text.AlignVCenter + font: quicksandFonts.bold14 + color: "#3E3853" + text: qsTr("Certificates") + } + } + + + Rectangle { + id: tableTitle + width: parent.width + height: 30 * pt + y: 40 * pt + color: "#3E3853" + + Text { + x: 15 * pt + height: parent.height + verticalAlignment: Text.AlignVCenter + font: quicksandFonts.medium11 + text: root.seletedCertificateAccessType + color: "white" + } + + Text { + id: infoTitleText + x: 15 * pt + anchors { + right: parent.right + rightMargin: 21 * pt + } + height: parent.height + verticalAlignment: Text.AlignVCenter + font: quicksandFonts.medium11 + text: qsTr("Info") + visible: root.infoTitleTextVisible + color: "white" + } + } + + } //header + + + Component { + id: delegateComponent + + Item { + //this property need set from root + width: root.width + height: 40 * pt + + Text { + id: certificateNameText + x: 14 * pt + width: 612 * pt + height: parent.height + verticalAlignment: Text.AlignVCenter + font: model.selected ? quicksandFonts.mediumBold16 : quicksandFonts.regular16 + text: model.completeBaseName //model.fileName + color: model.selected ? "#D51F5D" : "#070023" + elide: Text.ElideRight + maximumLineCount: 1 + } + + + MouseArea{ + id: delegateClicked + width: parent.width + height: parent.height + onClicked: { + root.selectedIndex(model.index) + } + + onDoubleClicked: { + root.infoClicked(model.index) + //root.selectedIndex(model.index) + } + } + + + ToolButton { + id: infoButton + anchors { + left: certificateNameText.right + right: parent.right + } + height: parent.height + visible: model.selected + + image.anchors { + right: infoButton.right + rightMargin: 14 * pt + } + image.source: "qrc:/resources/icons/Certificates/ic_info.svg" + image.width: 30 * pt + image.height: 30 * pt + + onClicked: { + root.infoClicked(model.index) + } + + } // + + + Rectangle { + id: bottomLine + x: certificateNameText.x + y: parent.height + width: 648 * pt + height: 1 * pt + color: "#E3E2E6" + } + + } // + + } //delegateComponent + + + + Rectangle { //border frame + width: parent.width + height: parent.height + border.color: "#E2E1E6" + border.width: 1 * pt + radius: 8 * pt + color: "transparent" + z: 1 + } + + + + + +} //root diff --git a/CellFrameDashboardGUI/screen/desktop/Certificates/CertificatesLogic.qml b/CellFrameDashboardGUI/screen/desktop/Certificates/CertificatesLogic.qml new file mode 100644 index 0000000..41c199e --- /dev/null +++ b/CellFrameDashboardGUI/screen/desktop/Certificates/CertificatesLogic.qml @@ -0,0 +1,288 @@ +import QtQuick 2.0 +import DapCertificateManager.Commands 1.0 + + +/* + reply from service format + result = { + command: <enumcommand> + status: "OK" | "FAIL", + errorMessage: "", //optional when error + data: ... //empty or object or array + } +*/ + + + +Item { + id: root + + //Ñигнализирует о выполнении запроÑа когда запущен реквеÑÑ‚ + property bool requestRunning: false + + + Component.onCompleted: { + dapServiceController.requestToService(DapCertificateCommands.serviceName + , DapCertificateCommands.GetSertificateList + ); + } + + + + Connections + { + target: dapServiceController + + onCertificateManagerOperationResult: { //const QVariant& result + if (!result) { + console.error("result is empty") + return + } + + utils.beatifulerJSONKeys(result, "onCertificateManagerOperationResult"); //for test + //messagePopup.smartOpen("Certificate", "result.errorMessage") + + requestRunning = false + + //common error message box + if (result.status !== DapCertificateCommands.statusOK) { + console.error("execute command %1, message %2" + .arg(DapCertificateCommands.commandToString(result.command)).arg(result.errorMessage)) + messagePopup.smartOpen(qsTr("Certificate"), result.errorMessage) + } + + + switch (result.command) { + case DapCertificateCommands.UnknownCommand: //0 + console.warn("DapCertificateCommands.UnknownCommand") + break; + case DapCertificateCommands.GetSertificateList: + if (!Array.isArray(result.data)) { + console.error("result.data not array") + return + } + + if (result.status === DapCertificateCommands.statusOK) { + models.certificates.parseFromCertList(result.data) + } + + break; + case DapCertificateCommands.CreateCertificate: + if (!(typeof result.data === "object")) { + console.error("result.data not object") + return + } + //utils.beatifulerJSON(result.data, "DapCertificateCommands.CreateCertificate") //for test + if (result.status === DapCertificateCommands.statusOK) { + models.certificates.prependFromObject(result.data) + models.certificates.clearSelected() + rightPanel.sourceComponent = createFinishedItemComponent + } + break; + case DapCertificateCommands.DumpCertifiacate: + //utils.beatifulerJSON(result, "DapCertificateCommands.DumpCertifiacate"); //for test + if (result.status === DapCertificateCommands.statusOK) { + models.certificateInfo.clear() + + models.certificateInfo.append({ key: "signature", + keyView: qsTr("Signature type") + , value: models.signatureKeyToViewName[result.data.signature] } ) + models.certificateInfo.append({ key: "name", + keyView: qsTr("Title") + , value: result.data.name } ) + + for (var i in result.data.metadata) { + var metadataElement = result.data.metadata[i] +// switch (metadataElement.key) { //date format +// case "creation_date": +// case "expiration_date": { +// //TODO need save date to ISO +// metadataElement.value = Qt.formatDate(new Date(metadataElement.value, '.', '-'), "dd MMM, yyyy") +// } +// break; +// } + + var keyView = models.metadataKeyToViewKey[metadataElement.key] + models.certificateInfo.append({ + key: metadataElement.key + , keyView: keyView ? keyView : metadataElement.key + , value: metadataElement.value + }) + } + } + break; + case DapCertificateCommands.ImportCertificate: + //TODO + break; + case DapCertificateCommands.ExportPublicCertificateToFile: + //utils.beatifulerJSON(result.data, "DapCertificateCommands.ExportPublicCertificateToFile") //for test + if (!(typeof result.data === "object")) { + console.error("result.data not object") + return + } + if (result.status === DapCertificateCommands.statusOK) { + models.certificates.clearSelected() + models.certificates.prependFromObject(result.data) + messagePopup.smartOpen(qsTr("Certificate"), "Public certificate created, file path:\n%1".arg(result.data.filePath)) + } + + break; + case DapCertificateCommands.ExportPublicCertificateToMempool: + //utils.beatifulerJSON(result, "DapCertificateCommands.ExportPublicCertificateToMempool") //for test + + if (!(typeof result.data === "object")) { + console.error("result.data not object") + return + } + + if (result.status === DapCertificateCommands.statusOK) { + messagePopup.smartOpen(qsTr("Certificate"), "Success export to mempool\ncertificate: %1\nnetwork: %2" + .arg(result.data.certName).arg(result.data.network)) + } + + break; + case DapCertificateCommands.AddSignatureToCertificate: + //TODO + break; + case DapCertificateCommands.DeleteCertificate: + //utils.beatifulerJSON(result.data, "DapCertificateCommands.DeleteCertificate"); //for test + if (result.status === DapCertificateCommands.statusOK) { + messagePopup.smartOpen(qsTr("Certificate"), qsTr("Certificate deleted\n%1").arg(result.data.deletedFilePath)) + models.certificates.removeByProperty("filePath", result.data.deletedFilePath) + models.certificates.clearSelected() + return + } + break; + + //пока что неиÑпользуемый Ñценарий + case DapCertificateCommands.UpdateCertificateList: //уведомление только еÑли изменÑетÑÑ Ð¿Ð°Ð¿ÐºÐ° Ñертификатов вручную + if (!Array.isArray(result.data)) { + console.error("result.data not array") + return + } + if (result.status === DapCertificateCommands.statusOK) { + models.certificates.parseFromCertList(result.data) + } + + break; + default: + console.error("onCertificateManagerOperationResult not valid command") + break; + } //switch + + } //onCertificateManagerOperationResult: + + + } //target: dapServiceController + + + //format "id", "fileName", "completeBaseName", "filePath", "dirType", "accessKeyType" + + function createCertificate(certName, certType, metaData){ //metaData is array of { type, , value } + console.info("FLOWPOINT createCertificate", certName, certType) + + dapServiceController.requestToService(DapCertificateCommands.serviceName + , DapCertificateCommands.CreateCertificate + , certName, certType + , JSON.stringify(metaData)); + } + + + //получение информации о Ñертификате + function dumpCertificate(index){ + var cert = models.certificates.get(index) + console.info("FLOWPOINT dumpCertificate, index", index) + + if (cert) { + dapServiceController.requestToService(DapCertificateCommands.serviceName + , DapCertificateCommands.DumpCertifiacate + , cert.completeBaseName, cert.filePath); //completeBaseName + } else + console.error("not valid index", index) + } + + + function exportPublicCertificateToFile(index){ //index from certificates model + var cert = models.certificates.get(index) + console.info("FLOWPOINT exportPublicCertificateToFile") + + if (cert) { + var certName = cert.completeBaseName + dapServiceController.requestToService(DapCertificateCommands.serviceName + , DapCertificateCommands.ExportPublicCertificateToFile + , certName, certName + "_public" ); + } else + console.error("not valid index", index) + } + + + function exportPublicCertificateToMempool(index){ //index from certificates model + var cert = models.certificates.get(index) + console.info("FLOWPOINT exportPublicCertificateToMempool, index", index) + + if (cert && dapServiceController.CurrentNetwork !== "") { + requestRunning = true //долгий запроÑ, требует индикации + dapServiceController.requestToService(DapCertificateCommands.serviceName + , DapCertificateCommands.ExportPublicCertificateToMempool + , dapServiceController.CurrentNetwork, cert.completeBaseName); + } else + console.error("not valid index or network", index, dapServiceController.CurrentNetwork) + } + + + + function deleteCertificate(index){ //index from certificates model + var cert = models.certificates.get(index) + console.info("FLOWPOINT deleteCertificate, index", index) + + if (cert) + dapServiceController.requestToService(DapCertificateCommands.serviceName + , DapCertificateCommands.DeleteCertificate + , cert.filePath); + else + console.error("not valid index", index) // + } + + + //TODO Import certificate + //TODO Add signature to certificate + + + +} //root + + + +/* simple stress test rpc + + + property int count: 10000 + property int calcCount: 0 + property var commandQueue: [] + + + Component.onCompleted: { + for (var i = 0; i < count; ++i) { + var comand = Math.floor(Math.random() * 10000 % DapCertificateCommands.UpdateCertificateList) + //console.info("send comand:", comand) + commandQueue.push(comand) + + dapServiceController.requestToService(DapCertificateCommands.serviceName + , comand); + } + } + + + Connections + { + target: dapServiceController + onCertificateManagerOperationResult: { //const QVariant& result + if (commandQueue[root.calcCount] === comand) + calcCount++ + if (root.count === root.calcCount) + console.info("stress test success") + } + + } //target: dapServiceController + +*/ diff --git a/CellFrameDashboardGUI/screen/desktop/Certificates/CertificatesMainPage.qml.autosave b/CellFrameDashboardGUI/screen/desktop/Certificates/CertificatesMainPage.qml.autosave new file mode 100644 index 0000000..e2d023f --- /dev/null +++ b/CellFrameDashboardGUI/screen/desktop/Certificates/CertificatesMainPage.qml.autosave @@ -0,0 +1,23 @@ +import QtQuick 2.0 +import QtQuick.Controls 2.0 + + +Rectangle +{ +// id: frameScreen + +// ///@detalis Frame widget. +// property alias dapFrame: frameScreen +// ///@detalis Screen components. +// property Item dapContenetItemScreen + +// anchors.fill: parent + +// // Install screen components +// Item +// { +// id: contenetItemScreen +// data: dapContenetItemScreen +// anchors.fill: parent +// } +} \ No newline at end of file diff --git a/CellFrameDashboardGUI/screen/desktop/Certificates/CertificatesModels.qml b/CellFrameDashboardGUI/screen/desktop/Certificates/CertificatesModels.qml new file mode 100644 index 0000000..e59fcb8 --- /dev/null +++ b/CellFrameDashboardGUI/screen/desktop/Certificates/CertificatesModels.qml @@ -0,0 +1,198 @@ +import QtQuick 2.0 +import DapCertificateManager.Commands 1.0 +import "parts" +import "models" + + + +Item { + id: root + property alias accessKeyType: accessKeyType + property alias certificates: certificates + property alias certificatesFind: certificatesFind + property alias certificateInfo: certificateInfo + + property alias signatureType: signatureType + property alias createCertificateOptional: createCertificateOptional + + + readonly property var signatureKeyToViewName: ({ + "sig_dil": qsTr("Crystal-Dylithium"), + "sig_bliss": qsTr("Bliss"), + "sig_picnic": qsTr("Picnic"), + "sig_tesla": qsTr("Tesla") + }) + + + readonly property var metadataKeyToViewKey: ({ + "creation_date": qsTr("Date of creation"), + "expiration_date": qsTr("Expiration date"), + "domain": qsTr("Domain"), + "organization": qsTr("Organization"), + "fullname": qsTr("Full name"), + "email": qsTr("Email"), + "description": qsTr("Description") + }) + + + ListModel { + id: accessKeyType + property int selectedIndex: 0 + //selected certificate with private and public key + readonly property bool bothTypeCertificateSelected: selectedIndex === 2 + + ListElement { name: qsTr("Public certificates"); type: "public"; selected: true } + ListElement { name: qsTr("Private certificates"); type: "private"; selected: false } + ListElement { name: qsTr("Both"); type: "both"; selected: false } + + function setSelectedIndex(index){ + selectedIndex = index + for (var i = 0; i < count; ++i) + setProperty(i, "selected", index === i) + } + } + + + ListModel { + id: certificateInfo + //format key, keyView, value + //keys: [certName, certSignatureType] - required + // [creation_date, domain, expiration_date, organization, fullname, email, description] - optional + + } + + + ListModel { + id: createCertificateOptional + //вообще Ñти ключи нужно вынеÑти в общее перечиÑление + //creation_date default key + ListElement { placeHolderText: qsTr("Domain"); key: "domain"; data: ""; inputFieldMask: ""; } + ListElement { placeHolderText: qsTr("Expiration date"); key: "expiration_date"; data: ""; inputFieldMask: "99.99.9999"; } + ListElement { placeHolderText: qsTr("Organization"); key: "organization"; data: ""; inputFieldMask: ""; } + ListElement { placeHolderText: qsTr("Full name"); key: "fullname"; data: ""; inputFieldMask: ""; } + ListElement { placeHolderText: qsTr("Email"); key: "email"; data: ""; inputFieldMask: ""; } + ListElement { placeHolderText: qsTr("Description"); key: "description"; data: ""; inputFieldMask: ""; } + + function dataClear(){ + for (var i = 0; i < count; ++i) + setProperty(i, "data", "") + } + + function getDataToJson(){ + var result = { creation_date: Qt.formatDateTime(new Date(), "dd.MM.yyyy") } + for (var i = 0; i < count; ++i) { + var item = get(i) + if (item.data !== "") { + result[item.key] = item.data + } + } + + return result + } + } //createCertificateOptional + + + + ListModel { //this common model + id: signatureType + ListElement { name: "Crystal-Dylithium"; signature: "sig_dil"; isRecomended: true } + ListElement { name: "Bliss"; signature: "sig_bliss"; isRecomended: false } + ListElement { name: "Picnic"; signature: "sig_picnic"; isRecomended: false } + ListElement { name: "Tesla"; signature: "sig_tesla"; isRecomended: false } + } + + + ListModel { + id: certificates + //format "fileName", "completeBaseName", "filePath", "dirType", "accessKeyType" + + property int selectedIndex: -1 + readonly property bool isSelected: selectedIndex >= 0 + + function prependFromObject(obj) { + obj.selected = false + insert(0, obj) + } + + function appendFromObject(obj) { + obj.selected = false + append(obj) + } + + function clearSelected() { + if (selectedIndex >= 0) { + setProperty(selectedIndex, "selected", false) + selectedIndex = -1 + } + } + + function setSelectedIndex(index){ + selectedIndex = index + for (var i = 0; i < count; ++i) + setProperty(i, "selected", index === i) + } + + function parseFromCertList(certList){ + clearSelected() + clear() + for (var i = 0; i < certList.length; ++i) { + certList[i].selected = false + //utils.beatifulerJSON(certList[i], "certList[%1]".arg(i)) //for test + append(certList[i]) + } + } + + + function removeByProperty(propertyName, value){ + for (var i = 0; i < count; ++i) { + var item = get(i) + if (item && typeof item[propertyName] !== "undefined") + if (item[propertyName] === value) { + remove(i) + return true + } + } + return false + } + + } //certificates + + + //find over certificate model + FindDelegateModel { + id: certificatesFind + model: certificates + + property string findString: "" + property int accessKeyTypeIndex: 0 //from DapCertificateType::accessKeyType + + function update() { + //console.info("update()", accessKeyTypeIndex, findString, items.count) + if (findString !== "") { //find by name and accessKeyTypeIndex + var fstr = findString.toLocaleLowerCase() + + predicate = function (obj) { + return obj.fileName.toLowerCase().indexOf(fstr) >= 0 + && obj.accessKeyType === accessKeyTypeIndex + } + renew() + return; + } else { //find only by accessKeyTypeIndex + predicate = function (obj) { + return obj.accessKeyType === accessKeyTypeIndex + } + renew() + return; + } + + //without find -> all items visible in view + // predicate = function(obj) { return true; } + // renew() + + } //update + + } //certificatesFind + + + +} // diff --git a/CellFrameDashboardGUI/screen/desktop/Certificates/CreateCertificateItem.qml b/CellFrameDashboardGUI/screen/desktop/Certificates/CreateCertificateItem.qml new file mode 100644 index 0000000..49d2632 --- /dev/null +++ b/CellFrameDashboardGUI/screen/desktop/Certificates/CreateCertificateItem.qml @@ -0,0 +1,232 @@ +import QtQuick 2.9 +import QtQuick.Layouts 1.2 +import QtQuick.Controls 2.2 +import "qrc:/widgets" +import "parts" + + + + +Rectangle { + id: root + property alias closeButton: closeButton + property alias createButton: createButton + property alias optionalModel: optionalRepeater.model + property alias signatureTypeCertificateComboBox: signatureTypeCertificateComboBox + property alias titleCertificateTextInput: titleCertificateTextInput + + property bool requiredFieldValid: false + + implicitWidth: 100 + implicitHeight: 200 + + border.color: "#E2E1E6" + border.width: 1 * pt + radius: 8 * pt + color: "transparent" + + //part animation on created and open + visible: false + opacity: visible ? 1.0 : 0.0 + Behavior on opacity { + NumberAnimation { + duration: 100 + easing.type: Easing.InOutQuad + } + } + + + Item { + id: titleRectangle + width: parent.width + height: 40 * pt + + CloseButton { + id: closeButton + } + + Text { + id: certificateTitleText + anchors{ + left: closeButton.right + leftMargin: 18 * pt + verticalCenter: closeButton.verticalCenter + } + font: quicksandFonts.bold14 + color: "#3E3853" + text: qsTr("Create certificate") + } + } //titleRectangle + + + Rectangle { + id: requiredTitle + width: parent.width + height: 30 * pt + y: 38 * pt + color: "#3E3853" + + Text { + x: 15 * pt + height: parent.height + verticalAlignment: Text.AlignVCenter + font: quicksandFonts.medium11 + text: qsTr("Required") + color: "white" + } + + } + + + Item { + id: requiredBody + y: requiredTitle.y + requiredTitle.height + width: parent.width + height: 138 * pt + + DapComboBox { + id: signatureTypeCertificateComboBox + // x: popup.visible ? sidePaddingActive * (-1) : sidePaddingNormal //??? + + anchors.verticalCenter: undefined + x: (parent.width - width) / 2 + y: 13 * pt + widthPopupComboBoxNormal: 280 * pt + widthPopupComboBoxActive: 313 * pt + heightComboBoxNormal: 32 * pt + heightComboBoxActive: 42 * pt + + comboBoxTextRole: ["name"] + mainLineText: qsTr("Signature type") + indicatorImageNormal: "qrc:/resources/icons/Certificates/icon_arrow_down.svg" //"qrc:/resources/icons/ic_arrow_drop_down_dark.png" + indicatorImageActive: "qrc:/resources/icons/Certificates/ic_arrow_up.svg" //qrc:/resources/icons/ic_arrow_drop_up.png" + sidePaddingNormal: 0 * pt + sidePaddingActive: 20 * pt + bottomIntervalListElement: 8 * pt + paddingTopItemDelegate: 8 * pt + heightListElement: 42 * pt + //intervalListElement: 10 * pt + indicatorWidth: 24 * pt + indicatorHeight: indicatorWidth + indicatorLeftInterval: 20 * pt + + normalColorText: "#070023" //#B4B1B placeholder color + hilightColorText: "#FFFFFF" + normalColorTopText: "#070023" + hilightColorTopText: "#070023" + hilightColor: "#D51F5D" //"#330F54" + normalTopColor: "transparent" + topEffect: false + normalColor: "#FFFFFF" + hilightTopColor: normalColor + colorTopNormalDropShadow: "#00000000" + colorDropShadow: "#40ABABAB" + fontComboBox: [quicksandFonts.regular16] + colorMainTextComboBox: [["#070023", "#070023"]] + colorTextComboBox: [["#070023", "#FFFFFF"]] + } + + + InputField { + id: titleCertificateTextInput + x: (parent.width - width) / 2 + y: 78 * pt + height: 28 * pt + width: 277 * pt + leftPadding: 0 + smartPlaceHolderText: qsTr("Title") + color: focus ? "#D51F5D" : "#070023" + font: quicksandFonts.regular16 + } + + + } //requiredBody + + + Rectangle { + id: optionalTitle + width: parent.width + height: 30 * pt + y: requiredBody.y + requiredBody.height + color: "#3E3853" + + Text { + x: 15 * pt + height: parent.height + verticalAlignment: Text.AlignVCenter + font: quicksandFonts.medium11 + text: qsTr("Optional") + color: "white" + } + + } //optionalTitle + + + Item { + id: optionalBody + y: optionalTitle.y + optionalTitle.height + width: parent.width + height: parent.height - y + + ColumnLayout { + id: optionalBodyLayout + spacing: 24 * pt + y: spacing + x: 15 * pt + width: parent.width - x + + Repeater { + id: optionalRepeater + + InputField { + Layout.preferredHeight: 28 * pt + Layout.preferredWidth: 277 * pt + leftPadding: 0 + smartPlaceHolderText: model.placeHolderText + color: focus ? "#D51F5D" : "#070023" + inputMask: model.inputFieldMask + + font: quicksandFonts.regular16 + onEditingFinished: { + text = text.trim() + optionalRepeater.model.setProperty(model.index, "data", text) + } + } + + } // + + + DapButton { + id: createButton + textButton: qsTr("Create") + Layout.preferredWidth: 132 * pt + Layout.preferredHeight: 36 * pt + Layout.alignment: Qt.AlignHCenter + + enabled: root.requiredFieldValid + colorBackgroundNormal: enabled ? "#271C4E" : "white" + colorBackgroundHover: enabled ? "#D2145D" : "white" + colorButtonTextNormal: enabled ? "#FFFFFF" : "#211A3A" + colorButtonTextHover: enabled ? "#FFFFFF" : "#211A3A" + borderColorButton: enabled ? "#000000" : "#211A3A" + borderWidthButton: enabled ? 0 : (1 * pt) + radius: 4 * pt + fontButton: quicksandFonts.regular16 + horizontalAligmentText: Qt.AlignHCenter + } + + + } //optionalBodyeLayout + + + } //optionalBody + + + + + + +} //root + + + diff --git a/CellFrameDashboardGUI/screen/desktop/Certificates/CreateFinishedItem.qml b/CellFrameDashboardGUI/screen/desktop/Certificates/CreateFinishedItem.qml new file mode 100644 index 0000000..d50d765 --- /dev/null +++ b/CellFrameDashboardGUI/screen/desktop/Certificates/CreateFinishedItem.qml @@ -0,0 +1,92 @@ +import QtQuick 2.9 +import "qrc:/widgets" +import "parts" + + + + +Rectangle { + id: root + property alias closeButton: closeButton + property alias doneButton: doneButton + property alias finishedText: finishedText + + implicitWidth: 100 + implicitHeight: 200 + + border.color: "#E2E1E6" + border.width: 1 * pt + radius: 8 * pt + color: "transparent" + + //part animation on created and open + visible: false + opacity: visible ? 1.0 : 0.0 + Behavior on opacity { + NumberAnimation { + duration: 100 + easing.type: Easing.InOutQuad + } + } + + + Item { + id: titleRectangle + width: parent.width + height: 40 * pt + + CloseButton { + id: closeButton + } // + + + Text { + id: certificatesTitleText + anchors{ + left: closeButton.right + leftMargin: 18 * pt + verticalCenter: closeButton.verticalCenter + } + font: quicksandFonts.bold14 + color: "#3E3853" + text: qsTr("Create certificate") + } + } //titleRectangle + + + Text { + id: finishedText + y: 202 * pt + anchors.horizontalCenter: parent.horizontalCenter + font: quicksandFonts.medium27 + color: "#070023" + text: qsTr("Certificate created\nsuccessfully") + horizontalAlignment: Text.AlignHCenter + } + + + DapButton { + id: doneButton + textButton: qsTr("Done") + y: 468 * pt + x: (parent.width - width) / 2 + height: 36 * pt + width: 132 * pt + colorBackgroundNormal: "#271C4E" + colorBackgroundHover: "#D2145D" + colorButtonTextNormal: "#FFFFFF" + colorButtonTextHover: "#FFFFFF" + borderColorButton: "#000000" + borderWidthButton: 0 + radius: 4 * pt + fontButton: quicksandFonts.regular16 + horizontalAligmentText: Qt.AlignHCenter + } + + + + +} //root + + + diff --git a/CellFrameDashboardGUI/screen/desktop/Certificates/DapCertificatesMainPage.qml b/CellFrameDashboardGUI/screen/desktop/Certificates/DapCertificatesMainPage.qml new file mode 100644 index 0000000..eeda098 --- /dev/null +++ b/CellFrameDashboardGUI/screen/desktop/Certificates/DapCertificatesMainPage.qml @@ -0,0 +1,320 @@ +import QtQuick 2.9 +import QtQuick.Controls 2.2 +import DapCertificateManager.Commands 1.0 +import "qrc:/widgets" +import "parts" + + +Rectangle +{ + id: dapCertificatesMainPage + + + Utils { + id: utils + } + + + + + CertificatesModels { + id: models + } + + CertificatesLogic{ + id: logics + } + + + HeaderItem { + id: headerItem + x: 3 * pt + width: parent.width + height: 60 * pt + + onFindHandler: { //text + models.certificatesFind.findString = text + models.certificatesFind.update() + } + } + + + + CertificatesListView { + id: certificatesListView + x: 24 * pt + y: 84 * pt + height: parent.height - y - 24 * pt + width: 678 * pt + infoTitleTextVisible: models.certificates.isSelected + + + Component.onCompleted: { + //need bind delegate with delegateModel + models.certificatesFind.delegate = delegateComponent + models.certificatesFind.accessKeyTypeIndex = DapCertificateType.Public //default open access type is public + models.certificatesFind.update() + model = models.certificatesFind //original +// delegate = delegateComponent +// model = models.certificates + } + + onSelectedIndex: { //index +// if (models.certificates.selectedIndex === index) //clear selected with repeat click +// models.certificates.clearSelected() +// else + models.certificates.setSelectedIndex(index) + } + + onInfoClicked: { //index + logics.dumpCertificate(index) + rightPanel.sourceComponent = certificateInfoComponent + } + + } //certificatesListView + + + Loader { + id: rightPanel + anchors { + right: parent.right + rightMargin: 26 * pt + } + asynchronous: true + y: certificatesListView.y + width: 348 * pt + height: certificatesListView.height + sourceComponent: certificatesActionsComponent + + onLoaded: { + item.visible = true + } + + } //rightPanel + + + + Component { + id: certificatesActionsComponent + + CertificatesActionsButtonList { + certificateSelected: models.certificates.isSelected + bothAccessTypeCertificateSelected: models.accessKeyType.bothTypeCertificateSelected + certificateAccessTypeRepeater.model: models.accessKeyType + + + onSelectedAccessKeyType: { //index + models.accessKeyType.setSelectedIndex(index) + models.certificates.clearSelected() + switch (index) { + case 0: //"public" + certificatesListView.seletedCertificateAccessType = qsTr("Public") + models.certificatesFind.accessKeyTypeIndex = DapCertificateType.Public + models.certificatesFind.update() + break; + case 1: //"private" + certificatesListView.seletedCertificateAccessType = qsTr("Private") + models.certificatesFind.accessKeyTypeIndex = DapCertificateType.Private + models.certificatesFind.update() + break; + case 2: //"both" + certificatesListView.seletedCertificateAccessType = qsTr("Both") + models.certificatesFind.accessKeyTypeIndex = DapCertificateType.Both + models.certificatesFind.update() + break; + default: + console.error("Unknown index", index) + break; + } + } + + + createCertificateButton.onClicked: { + rightPanel.sourceComponent = createCertificateComponent + } + + exportPublicCertificateToFileButton.onClicked: { + logics.exportPublicCertificateToFile(models.certificates.selectedIndex) + } + + exportPublicCertificateToMempoolButton.onClicked: { + logics.exportPublicCertificateToMempool(models.certificates.selectedIndex) + } + + deleteCertificateButton.onClicked: { + logics.deleteCertificate(models.certificates.selectedIndex) + } + + //TODO +// importCertificateButton +// addSignatureToCertificateButton + + } // + } //certificatesActionsComponent + + + Component { + id: createCertificateComponent + CreateCertificateItem { + optionalModel: models.createCertificateOptional + signatureTypeCertificateComboBox.model: models.signatureType + requiredFieldValid: false //TODO + + function checkRequiredField(){ + requiredFieldValid = titleCertificateTextInput.text.length > 0 + && signatureTypeCertificateComboBox.currentIndex >= 0 + } + + function checkOptionalField(){ + for (var i = 0; i < models.createCertificateOptional.count; ++i) { + var optionalField = models.createCertificateOptional.get(i) + var data = optionalField.data + switch (optionalField.key) { + case "domain": + if (data !== "" && !utils.validDomain(optionalField.data)) { + messagePopup.smartOpen(qsTr("%1 not correct").arg(optionalField.placeHolderText) + , "Please fill field correctly.") + return false; + } + break; + case "expiration_date": + if (data !== "" && !utils.validDate(optionalField.data)) { + messagePopup.smartOpen(qsTr("%1 not correct").arg(optionalField.placeHolderText) + , "Please fill field correctly.") + return false; + } + break; + case "email": + if (data !== "" && !utils.validEmail(optionalField.data)) { + messagePopup.smartOpen(qsTr("%1 not correct").arg(optionalField.placeHolderText) + , "Please fill field correctly.") + return false; + } + break; + } + } + + return true; + } + + signatureTypeCertificateComboBox.onCurrentIndexChanged: { + checkRequiredField() + } + + closeButton.onClicked: { + rightPanel.sourceComponent = certificatesActionsComponent + } + + createButton.onClicked: { //enabled when requiredFieldValid + if (checkOptionalField()) + logics.createCertificate(titleCertificateTextInput.text + , models.signatureType.get(signatureTypeCertificateComboBox.currentIndex).signature + , models.createCertificateOptional.getDataToJson()) + else + console.warn("not valid optional field") + } + + titleCertificateTextInput.onEditingFinished: { + checkRequiredField() + } + + titleCertificateTextInput.onTextChanged: { + checkRequiredField() + } + + + } + } //createCertificateComponent + + Component { + id: createFinishedItemComponent + CreateFinishedItem { + doneButton.onClicked: { + rightPanel.sourceComponent = certificatesActionsComponent + } + } + } + + Component { + id: certificateInfoComponent + CertificateInfoItem { + certificateDataListView.model: models.certificateInfo + closeButton.onClicked: { + rightPanel.sourceComponent = certificatesActionsComponent + } + } + } + + + Popup{ + id: messagePopup + closePolicy: "NoAutoClose" + padding: 0 + background: Item { } + width: dapMessageBox.width + height: dapMessageBox.height + x: (parent.width - width) / 2 + y: (parent.height - height) / 2 + modal: true + + function smartOpen(title, contentText) { + dapMessageBox.dapTitleText.text = title + dapMessageBox.dapContentText.text = contentText + open() + } + + DapMessageBox { + id: dapMessageBox + width: 240 * pt + height: 240 * pt + dapButtonOk.onClicked: { + messagePopup.close() + } + } + } + + + + + + Loader { + id: blockBusyIndicatorLoader + active: logics.requestRunning + width: parent.width + height: parent.height + sourceComponent: Component { + Popup{ + id: messagePopup + closePolicy: "NoAutoClose" + padding: 0 + background: Rectangle{ + width: parent.width + height: parent.height + radius: 12 * pt + } + width: dapMessageBox.width + height: dapMessageBox.height + x: (blockBusyIndicatorLoader.width - width) / 2 + y: (blockBusyIndicatorLoader.height - height) / 2 + modal: true + + BusyIndicator { + anchors.centerIn: parent + width: 120 * pt + height: 120 * pt + running: true + } + } + } + + onLoaded: { + item.parent = dapCertificatesMainPage + item.open() + } + } // + + + + + +} //dapCertificatesMainPage diff --git a/CellFrameDashboardGUI/screen/desktop/Certificates/HeaderItem.qml b/CellFrameDashboardGUI/screen/desktop/Certificates/HeaderItem.qml new file mode 100644 index 0000000..c526750 --- /dev/null +++ b/CellFrameDashboardGUI/screen/desktop/Certificates/HeaderItem.qml @@ -0,0 +1,58 @@ +import QtQuick 2.4 +import QtQuick.Controls 2.0 +import "qrc:/widgets" +import "parts" + + + +Rectangle { + id: root + + signal findHandler(string text) + + //color: "#211A3A" //design color + color: "#070023" //original color + radius: 8 * pt + + + implicitWidth: searchBox.x + searchBox.width + implicitHeight: searchBox.y + searchBox.height + + + + SearchInputBox { + id: searchBox + x: 38 * pt + anchors.verticalCenter: parent.verticalCenter + + placeholderText: qsTr("Search") + height: 28 * pt + width: Math.max(Math.min(leftPadding + contentWidth, root.width - searchBox.x * 2), 228 * pt) + color: "#B0AEB9" + font: quicksandFonts.regular14 + + onEditingFinished: { + filtering.clear() + root.findHandler(text) + } + + filtering.waitInputInterval: 100 + filtering.minimumSymbol: 0 + filtering.onAwaitingFinished: { + root.findHandler(text) + } + + } + + + //right Rectangle + Rectangle { + color: parent.color + height: parent.height + width: parent.radius + x: parent.width - width + } + + +} //root + diff --git a/CellFrameDashboardGUI/screen/desktop/Certificates/models/FindDelegateModel.qml b/CellFrameDashboardGUI/screen/desktop/Certificates/models/FindDelegateModel.qml new file mode 100644 index 0000000..38c2dfb --- /dev/null +++ b/CellFrameDashboardGUI/screen/desktop/Certificates/models/FindDelegateModel.qml @@ -0,0 +1,73 @@ +import QtQuick 2.9 +import QtQml.Models 2.3 + + +/* + + need move to common module + + +*/ + + + +DelegateModel { + id: root + items.includeByDefault: false + + + property var predicate: function(obj) { return true; } + + + function clear() { //move from visible and pending group to unusable group + console.log("FindDelegateModel.clear()", items.count, pendingItems.count) + if (items.count > 0) + items.setGroups(0, items.count, "unusable") + if (pendingItems.count > 0) + pendingItems.setGroups(0, pendingItems.count, "unusable") + } + + + function renew() { //find in base model +// console.log("FindDelegateModel.renew(), items.count: %1, unusableItems.count: %2, pendingItems.count: %3" +// .arg(items.count).arg(unusableItems.count).arg(pendingItems.count)) + + if (items.count > 0) + items.setGroups(0, items.count, "pending") + if (unusableItems.count > 0) + unusableItems.setGroups(0, unusableItems.count, "pending") + } + + + groups: [ + DelegateModelGroup { //item wait for find + id: pendingItems + name: "pending" + + includeByDefault: true + onChanged: { + while (pendingItems.count > 0) { + var item = pendingItems.get(0) + + if (predicate(item.model)) + item.groups = "items" + else + item.groups = "unusable" + } + } + }, //pending group end + DelegateModelGroup { //item no equal by find predicate + id: unusableItems + name: "unusable" + includeByDefault: false + +// onChanged: { +// console.log("unusableItems.onChanged:, unusableItems.count:", unusableItems.count) +// } + } + ] + + + +} //root + diff --git a/CellFrameDashboardGUI/screen/desktop/Certificates/parts/CloseButton.qml b/CellFrameDashboardGUI/screen/desktop/Certificates/parts/CloseButton.qml new file mode 100644 index 0000000..06d86ce --- /dev/null +++ b/CellFrameDashboardGUI/screen/desktop/Certificates/parts/CloseButton.qml @@ -0,0 +1,22 @@ +import QtQuick 2.0 + + +//fixed define button fo module certificate + + +ToolButton { + id: root + x: 14 * pt + y: 6 * pt + height: 28 * pt + width: height + + image.anchors { + right: root.right + rightMargin: 14 * pt + } + image.source: isHovered ? "qrc:/resources/icons/Certificates/close_icon_hover.svg" + : "qrc:/resources/icons/Certificates/close_icon.svg" + image.width: 20 * pt + image.height: 20 * pt +} // diff --git a/CellFrameDashboardGUI/screen/desktop/Certificates/parts/CreateCertificateModel.qml b/CellFrameDashboardGUI/screen/desktop/Certificates/parts/CreateCertificateModel.qml new file mode 100644 index 0000000..dcdcf70 --- /dev/null +++ b/CellFrameDashboardGUI/screen/desktop/Certificates/parts/CreateCertificateModel.qml @@ -0,0 +1,15 @@ +import QtQuick 2.0 + + + +//Ñтот компонент должен лежать в подкаталоге models + + + +Item { + + + + + +} diff --git a/CellFrameDashboardGUI/screen/desktop/Certificates/parts/FindDelegateModel.qml b/CellFrameDashboardGUI/screen/desktop/Certificates/parts/FindDelegateModel.qml new file mode 100644 index 0000000..4d98810 --- /dev/null +++ b/CellFrameDashboardGUI/screen/desktop/Certificates/parts/FindDelegateModel.qml @@ -0,0 +1,73 @@ +import QtQuick 2.9 +import QtQml.Models 2.3 + + +/* + + need move to common module + + +*/ + + + +DelegateModel { + id: root + items.includeByDefault: false + + + property var predicate: function(obj) { return true; } + + + function clear() { //move from visible and pending group to unusable group + console.log("FindDelegateModel.clear()", items.count, pendingItems.count) + if (items.count > 0) + items.setGroups(0, items.count, "unusable") + if (pendingItems.count > 0) + pendingItems.setGroups(0, pendingItems.count, "unusable") + } + + + function renew() { //find in base model + console.log("FindDelegateModel.renew(), items.count: %1, unusableItems.count: %2, pendingItems.count: %3" + .arg(items.count).arg(unusableItems.count).arg(pendingItems.count)) + + if (items.count > 0) + items.setGroups(0, items.count, "pending") + if (unusableItems.count > 0) + unusableItems.setGroups(0, unusableItems.count, "pending") + } + + + groups: [ + DelegateModelGroup { //item wait for find + id: pendingItems + name: "pending" + + includeByDefault: true + onChanged: { + while (pendingItems.count > 0) { + var item = pendingItems.get(0) + + if (predicate(item.model)) + item.groups = "items" + else + item.groups = "unusable" + } + } + }, //pending group end + DelegateModelGroup { //item no equal by find predicate + id: unusableItems + name: "unusable" + includeByDefault: false + +// onChanged: { +// console.log("unusableItems.onChanged:, unusableItems.count:", unusableItems.count) +// } + } + ] + + + +} //root + diff --git a/CellFrameDashboardGUI/screen/desktop/Certificates/parts/InputField.qml b/CellFrameDashboardGUI/screen/desktop/Certificates/parts/InputField.qml new file mode 100644 index 0000000..15d7633 --- /dev/null +++ b/CellFrameDashboardGUI/screen/desktop/Certificates/parts/InputField.qml @@ -0,0 +1,78 @@ +import QtQuick 2.9 +import QtQuick.Controls 2.2 +import QtQuick.Layouts 1.3 + + +//NOTE not use inner placeholderText: +//part common module + + +TextField { + id: root + + property alias borderLine: borderLine + property alias borderRadius: borderLine.radius + property alias placeholderTextView: placeholderTextView + + property string smartPlaceHolderText: "" + //placeholderTextColor: color //5.12 + property string placeholderTextColor: "#C7C6CE" //5.10 + + property int borderWidth: 1 * pt + property int borderWidthWhenFocus: 2 * pt + + property color backgroundColor: "transparent" + property color backgroundColorWhenDisabled: backgroundColor + property color borderColor: "#C7C6CE" + property color borderColorWhenDisabled: borderColor + + + color: "#070023" + verticalAlignment: TextInput.AlignVCenter + selectByMouse: false + //inputMethodHints: Qt.ImhPreferLowercase + + leftPadding: 12 * pt + rightPadding: 6 * pt + topPadding: 3 * pt + bottomPadding: 6 * pt + + + Text { + id: placeholderTextView + visible: root.displayText === "" + color: root.placeholderTextColor + text: root.smartPlaceHolderText + anchors.fill: parent + + verticalAlignment: root.verticalAlignment + horizontalAlignment: root.horizontalAlignment + elide: Text.ElideRight + + leftPadding: root.leftPadding + rightPadding: root.rightPadding + topPadding: root.topPadding + bottomPadding: root.bottomPadding + + font: root.font + } + + + Rectangle { + id: borderLine + z: -1 + anchors.bottom: parent.bottom + width: parent.width + height: 1 * pt + color: root.enabled ? backgroundColor : backgroundColorWhenDisabled + border.color: root.enabled ? borderColor : borderColorWhenDisabled + border.width: root.activeFocus ? borderWidthWhenFocus : borderWidth + } + + + //empty default background + background: Item { } + + + +} //root diff --git a/CellFrameDashboardGUI/screen/desktop/Certificates/parts/PlaceholderTextView.qml.autosave b/CellFrameDashboardGUI/screen/desktop/Certificates/parts/PlaceholderTextView.qml.autosave new file mode 100644 index 0000000..75ef5b3 --- /dev/null +++ b/CellFrameDashboardGUI/screen/desktop/Certificates/parts/PlaceholderTextView.qml.autosave @@ -0,0 +1,13 @@ +import QtQuick 2.9 +import QtQuick.Controls 2.2 +import QtQuick.Layouts 1.3 + + + +Item { + + + + + +} diff --git a/CellFrameDashboardGUI/screen/desktop/Certificates/parts/SearchInputBox.qml b/CellFrameDashboardGUI/screen/desktop/Certificates/parts/SearchInputBox.qml new file mode 100644 index 0000000..cb2e2c1 --- /dev/null +++ b/CellFrameDashboardGUI/screen/desktop/Certificates/parts/SearchInputBox.qml @@ -0,0 +1,103 @@ +import QtQuick 2.9 +import QtQuick.Controls 2.0 +import QtQuick.Layouts 1.3 + + +/* + + need move to common module + + +*/ + + + +TextField { + id: root + + property alias filtering: filtering + property alias searchImage: searchImage + property int spacing: 10 * pt + + + implicitHeight: 50 * pt + implicitWidth: 100 * pt + leftPadding: searchImage.width + spacing + font.pixelSize: 14 * pt + topPadding: 0 + bottomPadding: 8 * pt + + + Image{ + id: searchImage + width: 20 * pt + height: 20 * pt + fillMode: Image.PreserveAspectFit + verticalAlignment: Image.AlignVCenter + horizontalAlignment: Image.AlignHCenter + + source: "qrc:/resources/icons/ic_search.png" + } + + background: Item { } + + + //bottom line + Rectangle { + width: parent.width + height: 1 * pt + y: parent.height + color: "#453F5A" + + Behavior on width { + NumberAnimation { + duration: 100 + easing.type: Easing.InOutQuad + } + } + } + + + onTextChanged: { + filtering.filter(text) + } + + //for mobile input + onDisplayTextChanged: { + filtering.filter(text) + } + + + //optional +// onAccepted: { +// console.log("SearchInputBox.onAccepted:", text) +// } + +// onEditingFinished: { +// filtering.clear() +// console.log("SearchInputBox.onEditingFinished:", text) +// } + + +// onTextEdited: { +// console.log("SearchInputBox.onEdited:", text) +// } + + + TextInputFilter { + id: filtering + minimumSymbol: 3 + waitInputInterval: 500 + onAwaitingFinished: { + //console.log("onAwaitingFinished:", text) + } + } + + + + +} // root + + + + diff --git a/CellFrameDashboardGUI/screen/desktop/Certificates/parts/TextInputFilter.qml b/CellFrameDashboardGUI/screen/desktop/Certificates/parts/TextInputFilter.qml new file mode 100644 index 0000000..4a45342 --- /dev/null +++ b/CellFrameDashboardGUI/screen/desktop/Certificates/parts/TextInputFilter.qml @@ -0,0 +1,70 @@ +import QtQuick 2.0 + + + +Item { + id: root + + signal awaitingFinished(string text) + + property alias blockInputInterval: blockInputTimer.interval + property alias waitInputInterval: waitInputTimer.interval + + readonly property alias validTextLength: pObj.validTextLength + readonly property alias awaitingValidText: pObj.awaitingValidText + + property int minimumSymbol: 3 + + + //for set text in text field without signal emited + function blockSignal(){ + blockInputTimer.restart() + } + + + //use this function for filtering text after changed in input field + function filter(text){ + pObj.validTextLength = text.length >= minimumSymbol + //console.log("TextInputFiltering.filter:", text, validTextLength) + + if (!blockInputTimer.running){ + if (validTextLength) { //минимум Ñимволов Ð´Ð»Ñ Ð¿Ð¾Ð¸Ñка адреÑов 3 + pObj.awaitingValidText = text + waitInputTimer.restart() + } + } + + } + + + function clear(){ + blockInputTimer.stop() + waitInputTimer.stop() + pObj.awaitingValidText = "" + } + + + Timer{ + id: blockInputTimer + interval: 600 + } + + Timer{ + id: waitInputTimer + interval: 1000 + onTriggered: { + awaitingFinished(pObj.awaitingValidText) //возможно неверный объект + } + } + + + QtObject{ + id: pObj + property bool validTextLength: false + property string awaitingValidText: "" + } + + +} //root + + diff --git a/CellFrameDashboardGUI/screen/desktop/Certificates/parts/TitleTextView.qml b/CellFrameDashboardGUI/screen/desktop/Certificates/parts/TitleTextView.qml new file mode 100644 index 0000000..d1075f3 --- /dev/null +++ b/CellFrameDashboardGUI/screen/desktop/Certificates/parts/TitleTextView.qml @@ -0,0 +1,39 @@ +import QtQuick 2.9 +import QtQuick.Layouts 1.3 + + + +Item { + id: root + + property alias title: title + property alias content: content + + property int verticalSpacing: 10 * pt + + + implicitWidth: Math.max(title.width, content.width) + implicitHeight: title.height + verticalSpacing + content.height + + + Text { + id: title + font: quicksandFonts.regular12 + color: "#B4B1BD" + elide: Text.ElideRight + maximumLineCount: 1 + } + + + + Text { + id: content + y: title.height + verticalSpacing + font: quicksandFonts.regular14 + color: "#070023" + elide: Text.ElideRight + maximumLineCount: 1 + } + + +} // diff --git a/CellFrameDashboardGUI/screen/desktop/Certificates/parts/ToolButton.qml b/CellFrameDashboardGUI/screen/desktop/Certificates/parts/ToolButton.qml new file mode 100644 index 0000000..e5ee924 --- /dev/null +++ b/CellFrameDashboardGUI/screen/desktop/Certificates/parts/ToolButton.qml @@ -0,0 +1,39 @@ +import QtQuick 2.9 + + +/* + + need move to common module + +*/ + + +MouseArea { + property alias image: image + property bool isHovered: false + + implicitHeight: 50 + implicitWidth: 50 + hoverEnabled: true + + onEntered: { + isHovered = true + } + + onExited: { + isHovered = false + } + + Image { + id: image + x: (parent.width - width) / 2 + y: (parent.height - height) / 2 + width: parent.width / 2 + height: parent.height / 2 + verticalAlignment: Image.AlignVCenter + horizontalAlignment: Image.AlignHCenter + } + + + +} // diff --git a/CellFrameDashboardGUI/screen/desktop/Certificates/parts/Utils.qml b/CellFrameDashboardGUI/screen/desktop/Certificates/parts/Utils.qml new file mode 100644 index 0000000..d3af1ba --- /dev/null +++ b/CellFrameDashboardGUI/screen/desktop/Certificates/parts/Utils.qml @@ -0,0 +1,72 @@ +import QtQuick 2.0 + +Item { + id: root + +// Component.onCompleted: { //for test +// console.log("valid test" +// , utils.validDate("05.05.2020") +// , utils.validDomain("mkyong-info.com") +// , utils.validEmail("mkyong...@info.com") +// , utils.validDate("05.55.2020") +// , utils.validDomain("mkyong?info.com") +// , utils.validEmail("mkyong//@info.com") ) + +// console.info(replaceChars("11.11.2222", '.', '-')) +// } + + + //litle beatifuler visual json, + function beatifulerJSON(json, message){ + console.log( (typeof message != 'undefined' ? message + ', ' : "") + , ':', JSON.stringify(json, null, ' ') ) //невыводит на больших маÑÑивах данных + } + + function beatifulerJSONKeys(json, message){ + console.log( (typeof message != 'undefined' ? message + ', ' : "") + , 'Keys:', JSON.stringify(Object.keys(json) + , null, ' ') ) + } + + + function validEmail(email){ + var regExp = /^[\w\.\d-_+]+@[\w\.\d-_+]+\.\w{2,4}$/i; //maybe $ in the end + return regExp.test(email) + } + + + function validDomain(domain){ + console.log("domain", domain) + var regExp = /^(?!\-)(?:[a-zA-Z\d\-]{0,62}[a-zA-Z\d]\.){1,126}(?!\d+)[a-zA-Z\d]{1,63}$/; + return regExp.test(domain) + } + + + function validDate(date){ + var regExp = /^(?:(?:31(\/|-|\.)(?:0?[13578]|1[02]))\1|(?:(?:29|30)(\/|-|\.)(?:0?[1,3-9]|1[0-2])\2))(?:(?:1[6-9]|[2-9]\d)?\d{2})$|^(?:29(\/|-|\.)0?2\3(?:(?:(?:1[6-9]|[2-9]\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00))))$|^(?:0?[1-9]|1\d|2[0-8])(\/|-|\.)(?:(?:0?[1-9])|(?:1[0-2]))\4(?:(?:1[6-9]|[2-9]\d)?\d{2})$/m; + return regExp.test(date) + } + + + function replaceChars(text, findChar, replaceChar){ + return text.split(findChar).join(replaceChar) + } + + + +} //root + + + + + + + + + + + + + + + diff --git a/CellFrameDashboardGUI/screen/desktop/Dashboard/RightPanel/DapInputNewWalletNameRightPanel.qml b/CellFrameDashboardGUI/screen/desktop/Dashboard/RightPanel/DapInputNewWalletNameRightPanel.qml index b9df394..2cd0de6 100644 --- a/CellFrameDashboardGUI/screen/desktop/Dashboard/RightPanel/DapInputNewWalletNameRightPanel.qml +++ b/CellFrameDashboardGUI/screen/desktop/Dashboard/RightPanel/DapInputNewWalletNameRightPanel.qml @@ -14,7 +14,9 @@ DapInputNewWalletNameRightPanelForm console.log(dapTextInputNameWallet.text) console.log(dapSignatureTypeWallet) console.log(dapServiceController.CurrentNetwork) - dapServiceController.requestToService("DapAddWalletCommand", dapTextInputNameWallet.text, dapSignatureTypeWallet, dapServiceController.CurrentNetwork, "0xad12dec5ab4f"); + dapServiceController.requestToService("DapAddWalletCommand", dapTextInputNameWallet.text //original + , dapSignatureTypeWallet, dapServiceController.CurrentNetwork + , "0xad12dec5ab4f"); } dapButtonClose.onClicked: diff --git a/CellFrameDashboardService/CellFrameDashboardService.pro b/CellFrameDashboardService/CellFrameDashboardService.pro index 25bb811..7b512ed 100755 --- a/CellFrameDashboardService/CellFrameDashboardService.pro +++ b/CellFrameDashboardService/CellFrameDashboardService.pro @@ -3,6 +3,12 @@ QT += core network gui widgets CONFIG += c++11 console CONFIG -= app_bundle + +LIBS += -ldl +#LIBS+=-lz #-lz -lrt -lm -lpthread -lrt -lm -lpthread +#+LIBS+=-lrt + + !defined(BRAND,var){ # Default brand BRAND = CellFrameDashboard @@ -19,11 +25,13 @@ win32 { CONFIG -= console VERSION = $${VER_MAJ}.$${VER_MIN}.$$VER_PAT DEFINES += CLI_PATH=\\\"cellframe-node-cli.exe\\\" + DEFINES += TOOLS_PATH=\\\"cellframe-node-tool.exe\\\" DEFINES += HAVE_STRNDUP } else { VERSION = $$VER_MAJ\.$$VER_MIN\-$$VER_PAT DEFINES += CLI_PATH=\\\"/opt/cellframe-node/bin/cellframe-node-cli\\\" + DEFINES += TOOLS_PATH=\\\"/opt/cellframe-node/bin/cellframe-node-tool\\\" DEFINES += LOG_FILE=\\\"/opt/cellframe-node/var/log/cellframe-node.log\\\" DEFINES += CMD_HISTORY=\\\"/opt/cellframe-dashboard/data/cmd_history.txt\\\" } diff --git a/CellFrameDashboardService/DapServiceController.cpp b/CellFrameDashboardService/DapServiceController.cpp index f4acca1..f376795 100755 --- a/CellFrameDashboardService/DapServiceController.cpp +++ b/CellFrameDashboardService/DapServiceController.cpp @@ -49,6 +49,9 @@ bool DapServiceController::start() /// Register command. void DapServiceController::registerCommand() { + //all certificates commands for module certificate in + m_pServer->addService(new DapCertificateManagerCommands("DapCertificateManagerCommands", m_pServer, CLI_PATH, TOOLS_PATH)); + // Application shutdown team m_pServer->addService(new DapQuitApplicationCommand("DapQuitApplicationCommand", m_pServer)); // GUI client activation command in case it is minimized/expanded diff --git a/CellFrameDashboardService/DapServiceController.h b/CellFrameDashboardService/DapServiceController.h index a9c7ed0..792893c 100755 --- a/CellFrameDashboardService/DapServiceController.h +++ b/CellFrameDashboardService/DapServiceController.h @@ -39,6 +39,8 @@ typedef class DapRpcLocalServer DapUiService; #include "handlers/DapRunCmdCommand.h" #include "handlers/DapGetHistoryExecutedCmdCommand.h" #include "handlers/DapSaveHistoryExecutedCmdCommand.h" +#include "handlers/DapCertificateManagerCommands.h" + #include "DapSystemTrayIcon.h" #include "DapToolTipWidget.h" -- GitLab