diff --git a/internal/frontend/bridge-gui/bridge-gui-tester/CMakeLists.txt b/internal/frontend/bridge-gui/bridge-gui-tester/CMakeLists.txt
index 812dcbc9..31de284e 100644
--- a/internal/frontend/bridge-gui/bridge-gui-tester/CMakeLists.txt
+++ b/internal/frontend/bridge-gui/bridge-gui-tester/CMakeLists.txt
@@ -66,11 +66,13 @@ add_executable(bridge-gui-tester
GRPCQtProxy.cpp GRPCQtProxy.h
GRPCService.cpp GRPCService.h
GRPCServerWorker.cpp GRPCServerWorker.h
+ Tabs/EventsTab.cpp Tabs/EventsTab.h
+ Tabs/KnowledgeBaseTab.cpp Tabs/KnowledgeBaseTab.h
Tabs/SettingsTab.cpp Tabs/SettingsTab.h
Tabs/UsersTab.cpp Tabs/UsersTab.h
UserDialog.cpp UserDialog.h
UserTable.cpp UserTable.h
- )
+)
target_precompile_headers(bridge-gui-tester PRIVATE Pch.h)
target_include_directories(bridge-gui-tester PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
diff --git a/internal/frontend/bridge-gui/bridge-gui-tester/GRPCService.cpp b/internal/frontend/bridge-gui/bridge-gui-tester/GRPCService.cpp
index 03ce14db..ec465236 100644
--- a/internal/frontend/bridge-gui/bridge-gui-tester/GRPCService.cpp
+++ b/internal/frontend/bridge-gui/bridge-gui-tester/GRPCService.cpp
@@ -367,7 +367,7 @@ grpc::Status GRPCService::RequestKnowledgeBaseSuggestions(ServerContext*, String
.url = QString("https://proton.me/support/bridge#%1").arg(i),
});
}
- qtProxy_.sendDelayedEvent(newKnowledgeBaseSuggestionsEvent(suggestions));
+ qtProxy_.sendDelayedEvent(newKnowledgeBaseSuggestionsEvent(app().mainWindow().knowledgeBaseTab().getSuggestions()));
return Status::OK;
}
@@ -377,19 +377,19 @@ grpc::Status GRPCService::RequestKnowledgeBaseSuggestions(ServerContext*, String
//****************************************************************************************************************************************************
Status GRPCService::ReportBug(ServerContext *, ReportBugRequest const *request, Empty *) {
app().log().debug(__FUNCTION__);
- SettingsTab &tab = app().mainWindow().settingsTab();
+ EventsTab const&eventsTab = app().mainWindow().eventsTab();
qtProxy_.reportBug(QString::fromStdString(request->ostype()), QString::fromStdString(request->osversion()),
QString::fromStdString(request->emailclient()), QString::fromStdString(request->address()), QString::fromStdString(request->description()),
request->includelogs());
SPStreamEvent event;
- switch (tab.nextBugReportResult()) {
- case SettingsTab::BugReportResult::Success:
+ switch (eventsTab.nextBugReportResult()) {
+ case EventsTab::BugReportResult::Success:
event = newReportBugSuccessEvent();
break;
- case SettingsTab::BugReportResult::Error:
+ case EventsTab::BugReportResult::Error:
event = newReportBugErrorEvent();
break;
- case SettingsTab::BugReportResult::DataSharingError:
+ case EventsTab::BugReportResult::DataSharingError:
event = newReportBugFallbackEvent();
break;
}
@@ -559,11 +559,11 @@ Status GRPCService::DiskCachePath(ServerContext *, Empty const *, StringValue *r
Status GRPCService::SetDiskCachePath(ServerContext *, StringValue const *path, Empty *) {
app().log().debug(__FUNCTION__);
- SettingsTab &tab = app().mainWindow().settingsTab();
+ EventsTab &eventsTab = app().mainWindow().eventsTab();
QString const qPath = QString::fromStdString(path->value());
// we mimic the behaviour of Bridge
- if (!tab.nextCacheChangeWillSucceed()) {
+ if (!eventsTab.nextCacheChangeWillSucceed()) {
qtProxy_.sendDelayedEvent(newDiskCacheErrorEvent(grpc::DiskCacheErrorType(CANT_MOVE_DISK_CACHE_ERROR)));
} else {
qtProxy_.setDiskCachePath(qPath);
@@ -643,7 +643,7 @@ Status GRPCService::Hostname(ServerContext *, Empty const *, StringValue *respon
//****************************************************************************************************************************************************
Status GRPCService::IsPortFree(ServerContext *, Int32Value const *request, BoolValue *response) {
app().log().debug(__FUNCTION__);
- response->set_value(app().mainWindow().settingsTab().isPortFree());
+ response->set_value(app().mainWindow().eventsTab().isPortFree());
return Status::OK;
}
diff --git a/internal/frontend/bridge-gui/bridge-gui-tester/MainWindow.cpp b/internal/frontend/bridge-gui/bridge-gui-tester/MainWindow.cpp
index 21dc9d8d..5f795c12 100644
--- a/internal/frontend/bridge-gui/bridge-gui-tester/MainWindow.cpp
+++ b/internal/frontend/bridge-gui/bridge-gui-tester/MainWindow.cpp
@@ -71,11 +71,27 @@ SettingsTab &MainWindow::settingsTab() {
//****************************************************************************************************************************************************
/// \return A reference to the users tab.
//****************************************************************************************************************************************************
-UsersTab &MainWindow::usersTab() {
+UsersTab &MainWindow::usersTab() const {
return *ui_.usersTab;
}
+//****************************************************************************************************************************************************
+/// \return A reference to the events tab.
+//****************************************************************************************************************************************************
+EventsTab& MainWindow::eventsTab() const {
+ return *ui_.eventsTab;
+}
+
+
+//****************************************************************************************************************************************************
+/// \return A reference to the knowledge base tab.
+//****************************************************************************************************************************************************
+KnowledgeBaseTab& MainWindow::knowledgeBaseTab() const {
+ return *ui_.knowledgeBaseTab;
+}
+
+
//****************************************************************************************************************************************************
/// \param[in] level The log level.
/// \param[in] message The log message
@@ -98,7 +114,7 @@ void MainWindow::addBridgeGUILogEntry(bridgepp::Log::Level level, const QString
/// \param[in] event The event.
//****************************************************************************************************************************************************
void MainWindow::sendDelayedEvent(SPStreamEvent const &event) {
- QTimer::singleShot(this->settingsTab().eventDelayMs(), [event] { app().grpc().sendEvent(event); });
+ QTimer::singleShot(this->eventsTab().eventDelayMs(), [event] { app().grpc().sendEvent(event); });
}
diff --git a/internal/frontend/bridge-gui/bridge-gui-tester/MainWindow.h b/internal/frontend/bridge-gui/bridge-gui-tester/MainWindow.h
index 439e1e84..b50b045e 100644
--- a/internal/frontend/bridge-gui/bridge-gui-tester/MainWindow.h
+++ b/internal/frontend/bridge-gui/bridge-gui-tester/MainWindow.h
@@ -39,7 +39,9 @@ public: // member functions.
MainWindow &operator=(MainWindow &&) = delete; ///< Disabled move assignment operator.
SettingsTab &settingsTab(); ///< Returns a reference the 'Settings' tab.
- UsersTab &usersTab(); ///< Returns a reference to the 'Users' tab.
+ UsersTab &usersTab() const; ///< Returns a reference to the 'Users' tab.
+ EventsTab &eventsTab() const; ///< Returns a reference to the 'Events' tab.
+ KnowledgeBaseTab &knowledgeBaseTab() const; ///< Returns a reference to the 'Knowledge Base' tab.
public slots:
void sendDelayedEvent(bridgepp::SPStreamEvent const &event); ///< Sends a gRPC event after the delay specified in the UI. The call is non blocking.
diff --git a/internal/frontend/bridge-gui/bridge-gui-tester/MainWindow.ui b/internal/frontend/bridge-gui/bridge-gui-tester/MainWindow.ui
index 703e875f..c0fdc8b6 100644
--- a/internal/frontend/bridge-gui/bridge-gui-tester/MainWindow.ui
+++ b/internal/frontend/bridge-gui/bridge-gui-tester/MainWindow.ui
@@ -6,8 +6,8 @@
0
0
- 1226
- 1086
+ 1096
+ 876
@@ -22,7 +22,7 @@
- 0
+ 3
@@ -34,6 +34,16 @@
Users
+
+
+ Events && Errors
+
+
+
+
+ Knowledge Base
+
+
@@ -96,6 +106,18 @@
1
+
+ EventsTab
+ QWidget
+
+ 1
+
+
+ KnowledgeBaseTab
+ QWidget
+
+ 1
+
diff --git a/internal/frontend/bridge-gui/bridge-gui-tester/Tabs/EventsTab.cpp b/internal/frontend/bridge-gui/bridge-gui-tester/Tabs/EventsTab.cpp
new file mode 100644
index 00000000..4d664aa7
--- /dev/null
+++ b/internal/frontend/bridge-gui/bridge-gui-tester/Tabs/EventsTab.cpp
@@ -0,0 +1,116 @@
+// Copyright (c) 2023 Proton AG
+//
+// This file is part of Proton Mail Bridge.
+//
+// Proton Mail Bridge is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Proton Mail Bridge is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Proton Mail Bridge. If not, see .
+
+
+#include "EventsTab.h"
+#include "GRPCService.h"
+#include
+
+
+using namespace bridgepp;
+
+
+//****************************************************************************************************************************************************
+/// \brief Connect an address error button to the generation of an address error event.
+///
+/// \param[in] button The error button.
+/// \param[in] edit The edit containing the address.
+/// \param[in] eventGenerator The factory function creating the event.
+//****************************************************************************************************************************************************
+void connectAddressError(QPushButton* button, QLineEdit* edit, bridgepp::SPStreamEvent (*eventGenerator)(QString const&)) {
+ QObject::connect(button, &QPushButton::clicked, [edit, eventGenerator]() { app().grpc().sendEvent(eventGenerator(edit->text())); });
+}
+
+
+//****************************************************************************************************************************************************
+/// \param[in] parent The parent widget.
+//****************************************************************************************************************************************************
+EventsTab::EventsTab(QWidget* parent)
+ : QWidget(parent) {
+ ui_.setupUi(this);
+ this->resetUI();
+
+ connect(ui_.buttonInternetOn, &QPushButton::clicked, []() { app().grpc().sendEvent(newInternetStatusEvent(true)); });
+ connect(ui_.buttonInternetOff, &QPushButton::clicked, []() { app().grpc().sendEvent(newInternetStatusEvent(false)); });
+ connect(ui_.buttonShowMainWindow, &QPushButton::clicked, []() { app().grpc().sendEvent(newShowMainWindowEvent()); });
+ connect(ui_.buttonNoKeychain, &QPushButton::clicked, []() { app().grpc().sendEvent(newHasNoKeychainEvent()); });
+ connect(ui_.buttonAPICertIssue, &QPushButton::clicked, []() { app().grpc().sendEvent(newApiCertIssueEvent()); });
+ connectAddressError(ui_.buttonAddressChanged, ui_.editAddressErrors, newAddressChangedEvent);
+ connectAddressError(ui_.buttonAddressChangedLogout, ui_.editAddressErrors, newAddressChangedLogoutEvent);
+ //connect(ui_.checkNextCacheChangeWillSucceed, &QCheckBox::toggled, this, &SettingsTab::updateGUIState);
+ connect(ui_.buttonUpdateError, &QPushButton::clicked, [&]() {
+ app().grpc().sendEvent(newUpdateErrorEvent(static_cast(ui_.comboUpdateError->currentIndex())));
+ });
+ connect(ui_.buttonUpdateManualReady, &QPushButton::clicked, [&] {
+ app().grpc().sendEvent(newUpdateManualReadyEvent(ui_.editUpdateVersion->text()));
+ });
+ connect(ui_.buttonUpdateForce, &QPushButton::clicked, [&] {
+ app().grpc().sendEvent(newUpdateForceEvent(ui_.editUpdateVersion->text()));
+ });
+ connect(ui_.buttonUpdateManualRestart, &QPushButton::clicked, []() { app().grpc().sendEvent(newUpdateManualRestartNeededEvent()); });
+ connect(ui_.buttonUpdateSilentRestart, &QPushButton::clicked, []() { app().grpc().sendEvent(newUpdateSilentRestartNeededEvent()); });
+ connect(ui_.buttonUpdateIsLatest, &QPushButton::clicked, []() { app().grpc().sendEvent(newUpdateIsLatestVersionEvent()); });
+ connect(ui_.buttonUpdateCheckFinished, &QPushButton::clicked, []() { app().grpc().sendEvent(newUpdateCheckFinishedEvent()); });
+ connect(ui_.buttonUpdateVersionChanged, &QPushButton::clicked, []() { app().grpc().sendEvent(newUpdateVersionChangedEvent()); });
+}
+
+
+//****************************************************************************************************************************************************
+/// \return The delay to apply before sending automatically generated events.
+//****************************************************************************************************************************************************
+qint32 EventsTab::eventDelayMs() const {
+ return ui_.spinEventDelay->value();
+}
+
+
+//****************************************************************************************************************************************************
+//
+//****************************************************************************************************************************************************
+void EventsTab::updateGUIState() {
+}
+
+
+//****************************************************************************************************************************************************
+/// \return The bug report results
+//****************************************************************************************************************************************************
+EventsTab::BugReportResult EventsTab::nextBugReportResult() const {
+ return static_cast(ui_.comboBugReportResult->currentIndex());
+}
+
+
+//****************************************************************************************************************************************************
+/// \return The reply for the next IsPortFree gRPC call.
+//****************************************************************************************************************************************************
+bool EventsTab::isPortFree() const {
+ return ui_.checkIsPortFree->isChecked();
+}
+
+//****************************************************************************************************************************************************
+/// \return The value for the 'Next Cache Change Will Succeed' check box.
+//****************************************************************************************************************************************************
+bool EventsTab::nextCacheChangeWillSucceed() const {
+ return ui_.checkNextCacheChangeWillSucceed->isChecked();
+}
+
+//****************************************************************************************************************************************************
+//
+//****************************************************************************************************************************************************
+void EventsTab::resetUI() const {
+ ui_.comboBugReportResult->setCurrentIndex(0);
+ ui_.checkIsPortFree->setChecked(true);
+ ui_.checkNextCacheChangeWillSucceed->setChecked(true);
+}
diff --git a/internal/frontend/bridge-gui/bridge-gui-tester/Tabs/EventsTab.h b/internal/frontend/bridge-gui/bridge-gui-tester/Tabs/EventsTab.h
new file mode 100644
index 00000000..dd036212
--- /dev/null
+++ b/internal/frontend/bridge-gui/bridge-gui-tester/Tabs/EventsTab.h
@@ -0,0 +1,60 @@
+// Copyright (c) 2023 Proton AG
+//
+// This file is part of Proton Mail Bridge.
+//
+// Proton Mail Bridge is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Proton Mail Bridge is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Proton Mail Bridge. If not, see .
+
+
+#ifndef BRIDGE_GUI_TESTER_EVENTS_TAB_H
+#define BRIDGE_GUI_TESTER_EVENTS_TAB_H
+
+
+#include "ui_EventsTab.h"
+
+
+//****************************************************************************************************************************************************
+/// \brief Events tabs
+//****************************************************************************************************************************************************
+class EventsTab: public QWidget {
+ Q_OBJECT
+
+public: // data types
+enum class BugReportResult {
+ Success = 0,
+ Error = 1,
+ DataSharingError = 2,
+}; ///< Enumeration for the result of bug report sending
+
+public: // member functions.
+ explicit EventsTab(QWidget *parent = nullptr); ///< Default constructor.
+ EventsTab(EventsTab const&) = delete; ///< Disabled copy-constructor.
+ EventsTab(EventsTab&&) = delete; ///< Disabled assignment copy-constructor.
+ ~EventsTab() override = default; ///< Destructor.
+ EventsTab& operator=(EventsTab const&) = delete; ///< Disabled assignment operator.
+ EventsTab& operator=(EventsTab&&) = delete; ///< Disabled move assignment operator.
+
+ qint32 eventDelayMs() const; ///< Get the delay for sending automatically generated events.
+ void updateGUIState(); ///< Update the GUI state.
+ BugReportResult nextBugReportResult() const; ///< Get the value of the 'Next bug report result' combo box.
+ bool isPortFree() const; ///< Get the value for the "Is Port Free" check box.
+ bool nextCacheChangeWillSucceed() const; ///< Get the value for the 'Next Cache Change will succeed' edit.
+
+ void resetUI() const; ///< Resets the UI.
+
+private: // data members
+ Ui::EventsTab ui_; ///< The UI for the widget.
+};
+
+
+#endif
\ No newline at end of file
diff --git a/internal/frontend/bridge-gui/bridge-gui-tester/Tabs/EventsTab.ui b/internal/frontend/bridge-gui/bridge-gui-tester/Tabs/EventsTab.ui
new file mode 100644
index 00000000..6e1a1fef
--- /dev/null
+++ b/internal/frontend/bridge-gui/bridge-gui-tester/Tabs/EventsTab.ui
@@ -0,0 +1,359 @@
+
+
+ EventsTab
+
+
+
+ 0
+ 0
+ 563
+ 571
+
+
+
+ Form
+
+
+ -
+
+
-
+
+
-
+
+
+ Delay applied before sending automatically generated events
+
+
+ Delay for asynchronous events
+
+
+
+ -
+
+
+ ms
+
+
+ -1
+
+
+ 3600000
+
+
+ 100
+
+
+ 0
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 1
+
+
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ Address related errors
+
+
+
-
+
+
-
+
+
+ Address
+
+
+
+ -
+
+
+ dummy.user@proton.me
+
+
+
+
+
+ -
+
+
-
+
+
+ Address Changed
+
+
+
+ -
+
+
+ Address Changed Logout
+
+
+
+
+
+
+
+
+ -
+
+
-
+
+
+ Next Cache Change will succeed
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 1
+
+
+
+
+ -
+
+
+ Reply true to the next 'Is Port Free' request.
+
+
+
+
+
+ -
+
+
-
+
+
+ Next bug report result
+
+
+
+ -
+
+
-
+
+ Success
+
+
+ -
+
+ Error
+
+
+ -
+
+ Data sharing error
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 1
+
+
+
+
+
+
+ -
+
+
+ 8
+
+
-
+
+
+ Update Manual Ready
+
+
+
+ -
+
+
+ 4.0
+
+
+
+ -
+
+
+ Update version changed
+
+
+
+ -
+
+
+ Update Force
+
+
+
+ -
+
+
+ Update manual restart
+
+
+
+ -
+
+
+ Update check finished
+
+
+
+ -
+
+
+ Update silent restart
+
+
+
+ -
+
+
+ QComboBox::AdjustToContents
+
+
-
+
+ Update manual error
+
+
+ -
+
+ Update force error
+
+
+ -
+
+ Update silent error
+
+
+
+
+ -
+
+
+ Update error
+
+
+
+ -
+
+
+ Update is latest
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 1
+
+
+
+
+
+
+ -
+
+
+ -1
+
+
+ 8
+
+
-
+
+
+ Internet On
+
+
+
+ -
+
+
+ Show Main Window
+
+
+
+ -
+
+
+ Internet Off
+
+
+
+ -
+
+
+ API Certficate Issue
+
+
+
+ -
+
+
+ No Keychain
+
+
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 200
+
+
+
+
+
+
+
+
+
+
+
diff --git a/internal/frontend/bridge-gui/bridge-gui-tester/Tabs/KnowledgeBaseTab.cpp b/internal/frontend/bridge-gui/bridge-gui-tester/Tabs/KnowledgeBaseTab.cpp
new file mode 100644
index 00000000..6763375c
--- /dev/null
+++ b/internal/frontend/bridge-gui/bridge-gui-tester/Tabs/KnowledgeBaseTab.cpp
@@ -0,0 +1,86 @@
+// Copyright (c) 2023 Proton AG
+//
+// This file is part of Proton Mail Bridge.
+//
+// Proton Mail Bridge is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Proton Mail Bridge is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Proton Mail Bridge. If not, see .
+
+
+#include "KnowledgeBaseTab.h"
+
+#include "GRPCService.h"
+#include "bridgepp/GRPC/EventFactory.h"
+
+
+using namespace bridgepp;
+
+
+//****************************************************************************************************************************************************
+/// \param[in] parent The parent widget of the tab.
+//****************************************************************************************************************************************************
+KnowledgeBaseTab::KnowledgeBaseTab(QWidget* parent)
+ : QWidget(parent) {
+ ui_.setupUi(this);
+
+ connect(ui_.checkSuggestion1, &QCheckBox::stateChanged, this, &KnowledgeBaseTab::updateGuiState);
+ connect(ui_.checkSuggestion2, &QCheckBox::stateChanged, this, &KnowledgeBaseTab::updateGuiState);
+ connect(ui_.checkSuggestion3, &QCheckBox::stateChanged, this, &KnowledgeBaseTab::updateGuiState);
+ connect(ui_.buttonSend, &QCheckBox::clicked, this, &KnowledgeBaseTab::sendKnowledgeBaseSuggestions);
+
+}
+
+//****************************************************************************************************************************************************
+/// \param[in] checkbox The check box.
+/// \param[in] widgets The widgets to conditionally enable.
+//****************************************************************************************************************************************************
+void enableWidgetsIfChecked(QCheckBox const* checkbox, QWidgetList const& widgets) {
+ bool const checked = checkbox->isChecked();
+ for (QWidget *const widget: widgets) {
+ widget->setEnabled(checked);
+ }
+}
+
+
+//****************************************************************************************************************************************************
+/// \return The suggestions.
+//****************************************************************************************************************************************************
+QList KnowledgeBaseTab::getSuggestions() const {
+ QList result;
+ if (ui_.checkSuggestion1->isChecked()) {
+ result.push_back({ .url = ui_.editUrl1->text(), .title = ui_.editTitle1->text() });
+ }
+ if (ui_.checkSuggestion2->isChecked()) {
+ result.push_back({ .url = ui_.editUrl2->text(), .title = ui_.editTitle2->text() });
+ }
+ if (ui_.checkSuggestion3->isChecked()) {
+ result.push_back({ .url = ui_.editUrl3->text(), .title = ui_.editTitle3->text() });
+ }
+ return result;
+}
+
+
+//****************************************************************************************************************************************************
+//
+//****************************************************************************************************************************************************
+void KnowledgeBaseTab::sendKnowledgeBaseSuggestions() const {
+ app().grpc().sendEvent(newKnowledgeBaseSuggestionsEvent(this->getSuggestions()));
+}
+
+//****************************************************************************************************************************************************
+//
+//****************************************************************************************************************************************************
+void KnowledgeBaseTab::updateGuiState() {
+ enableWidgetsIfChecked(ui_.checkSuggestion1, { ui_.labelTitle1, ui_.editTitle1, ui_.labelUrl1, ui_.editUrl1});
+ enableWidgetsIfChecked(ui_.checkSuggestion2, { ui_.labelTitle2, ui_.editTitle2, ui_.labelUrl2, ui_.editUrl2});
+ enableWidgetsIfChecked(ui_.checkSuggestion3, { ui_.labelTitle3, ui_.editTitle3, ui_.labelUrl3, ui_.editUrl3});
+}
diff --git a/internal/frontend/bridge-gui/bridge-gui-tester/Tabs/KnowledgeBaseTab.h b/internal/frontend/bridge-gui/bridge-gui-tester/Tabs/KnowledgeBaseTab.h
new file mode 100644
index 00000000..87a79c06
--- /dev/null
+++ b/internal/frontend/bridge-gui/bridge-gui-tester/Tabs/KnowledgeBaseTab.h
@@ -0,0 +1,50 @@
+// Copyright (c) 2023 Proton AG
+//
+// This file is part of Proton Mail Bridge.
+//
+// Proton Mail Bridge is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Proton Mail Bridge is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Proton Mail Bridge. If not, see .
+
+
+#ifndef BRIDGE_GUI_TESTER_KNOWLEDGE_BASE_TAB_H
+#define BRIDGE_GUI_TESTER_KNOWLEDGE_BASE_TAB_H
+
+
+#include "ui_KnowledgeBaseTab.h"
+#include
+
+
+//****************************************************************************************************************************************************
+/// \brief Knowledge base table.
+//****************************************************************************************************************************************************
+class KnowledgeBaseTab: public QWidget {
+public: // member functions.
+ explicit KnowledgeBaseTab(QWidget *parent = nullptr); ///< Default constructor.
+ KnowledgeBaseTab(KnowledgeBaseTab const&) = delete; ///< Disabled copy-constructor.
+ KnowledgeBaseTab(KnowledgeBaseTab&&) = delete; ///< Disabled assignment copy-constructor.
+ ~KnowledgeBaseTab() override = default; ///< Destructor.
+ KnowledgeBaseTab& operator=(KnowledgeBaseTab const&) = delete; ///< Disabled assignment operator.
+ KnowledgeBaseTab& operator=(KnowledgeBaseTab&&) = delete; ///< Disabled move assignment operator.
+ QList getSuggestions() const; ///< Returns the suggestions.
+
+private slots:
+ void sendKnowledgeBaseSuggestions() const; ///< Send a KnowledgeBaseSuggestions event.
+ void updateGuiState(); ///< Update the GUI state.
+
+private: // data members
+ Ui::KnowledgeBaseTab ui_ {}; ///< The UI for the widget.
+};
+
+
+
+#endif //BRIDGE_GUI_TESTER_KNOWLEDGE_BASE_TAB_H
diff --git a/internal/frontend/bridge-gui/bridge-gui-tester/Tabs/KnowledgeBaseTab.ui b/internal/frontend/bridge-gui/bridge-gui-tester/Tabs/KnowledgeBaseTab.ui
new file mode 100644
index 00000000..f66f267d
--- /dev/null
+++ b/internal/frontend/bridge-gui/bridge-gui-tester/Tabs/KnowledgeBaseTab.ui
@@ -0,0 +1,202 @@
+
+
+ KnowledgeBaseTab
+
+
+
+ 0
+ 0
+ 483
+ 715
+
+
+
+ Form
+
+
+
+ 5
+
+ -
+
+
+ Suggestion 1
+
+
+
-
+
+
+ Enabled
+
+
+ true
+
+
+
+ -
+
+
+ Title
+
+
+
+ -
+
+
+ Automatically start Bridge
+
+
+
+ -
+
+
+ URL
+
+
+
+ -
+
+
+ https://proton.me/support/automatically-start-bridge
+
+
+
+
+
+
+ -
+
+
+ Suggestion 2
+
+
+
-
+
+
+ Enabled
+
+
+ true
+
+
+
+ -
+
+
+ Title
+
+
+
+ -
+
+
+ Proton Mail Bridge connection issues with Thunderbird, Outlook, and Apple Mail
+
+
+
+ -
+
+
+ URL
+
+
+
+ -
+
+
+ https://proton.me/support/bridge-ssl-connection-issue
+
+
+
+
+
+
+ -
+
+
+ Suggestion 3
+
+
+
-
+
+
+ Enabled
+
+
+ true
+
+
+
+ -
+
+
+ Title
+
+
+
+ -
+
+
+ Difference between combined addresses mode and split addresses mode
+
+
+
+ -
+
+
+ URL
+
+
+
+ -
+
+
+ https://proton.me/support/difference-combined-addresses-mode-split-addresses-mode
+
+
+
+
+
+
+ -
+
+
-
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ Send Knowledge Base Suggestions
+
+
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 0
+
+
+
+
+
+
+
+
+
diff --git a/internal/frontend/bridge-gui/bridge-gui-tester/Tabs/SettingsTab.cpp b/internal/frontend/bridge-gui/bridge-gui-tester/Tabs/SettingsTab.cpp
index e8ba0137..4538eb29 100644
--- a/internal/frontend/bridge-gui/bridge-gui-tester/Tabs/SettingsTab.cpp
+++ b/internal/frontend/bridge-gui/bridge-gui-tester/Tabs/SettingsTab.cpp
@@ -31,18 +31,6 @@ QString const colorSchemeLight = "light"; ///< THe light color scheme name.
}
-//****************************************************************************************************************************************************
-/// \brief Connect an address error button to the generation of an address error event.
-///
-/// \param[in] button The error button.
-/// \param[in] edit The edit containing the address.
-/// \param[in] eventGenerator The factory function creating the event.
-//****************************************************************************************************************************************************
-void connectAddressError(QPushButton *button, QLineEdit* edit, bridgepp::SPStreamEvent (*eventGenerator)(QString const &)) {
- QObject::connect(button, &QPushButton::clicked, [edit, eventGenerator]() { app().grpc().sendEvent(eventGenerator(edit->text())); });
-}
-
-
//****************************************************************************************************************************************************
/// \param[in] parent The parent widget of the tab.
//****************************************************************************************************************************************************
@@ -50,29 +38,6 @@ SettingsTab::SettingsTab(QWidget *parent)
: QWidget(parent) {
ui_.setupUi(this);
- connect(ui_.buttonInternetOn, &QPushButton::clicked, []() { app().grpc().sendEvent(newInternetStatusEvent(true)); });
- connect(ui_.buttonInternetOff, &QPushButton::clicked, []() { app().grpc().sendEvent(newInternetStatusEvent(false)); });
- connect(ui_.buttonShowMainWindow, &QPushButton::clicked, []() { app().grpc().sendEvent(newShowMainWindowEvent()); });
- connect(ui_.buttonNoKeychain, &QPushButton::clicked, []() { app().grpc().sendEvent(newHasNoKeychainEvent()); });
- connect(ui_.buttonAPICertIssue, &QPushButton::clicked, []() { app().grpc().sendEvent(newApiCertIssueEvent()); });
- connectAddressError(ui_.buttonAddressChanged, ui_.editAddressErrors, newAddressChangedEvent);
- connectAddressError(ui_.buttonAddressChangedLogout, ui_.editAddressErrors, newAddressChangedLogoutEvent);
- connect(ui_.checkNextCacheChangeWillSucceed, &QCheckBox::toggled, this, &SettingsTab::updateGUIState);
- connect(ui_.buttonUpdateError, &QPushButton::clicked, [&]() {
- app().grpc().sendEvent(newUpdateErrorEvent(static_cast(ui_.comboUpdateError->currentIndex())));
- });
- connect(ui_.buttonUpdateManualReady, &QPushButton::clicked, [&] {
- app().grpc().sendEvent(newUpdateManualReadyEvent(ui_.editUpdateVersion->text()));
- });
- connect(ui_.buttonUpdateForce, &QPushButton::clicked, [&] {
- app().grpc().sendEvent(newUpdateForceEvent(ui_.editUpdateVersion->text()));
- });
- connect(ui_.buttonUpdateManualRestart, &QPushButton::clicked, []() { app().grpc().sendEvent(newUpdateManualRestartNeededEvent()); });
- connect(ui_.buttonUpdateSilentRestart, &QPushButton::clicked, []() { app().grpc().sendEvent(newUpdateSilentRestartNeededEvent()); });
- connect(ui_.buttonUpdateIsLatest, &QPushButton::clicked, []() { app().grpc().sendEvent(newUpdateIsLatestVersionEvent()); });
- connect(ui_.buttonUpdateCheckFinished, &QPushButton::clicked, []() { app().grpc().sendEvent(newUpdateCheckFinishedEvent()); });
- connect(ui_.buttonUpdateVersionChanged, &QPushButton::clicked, []() { app().grpc().sendEvent(newUpdateVersionChangedEvent()); });
-
this->resetUI();
this->updateGUIState();
}
@@ -235,14 +200,6 @@ void SettingsTab::setIsTelemetryDisabled(bool isDisabled) {
}
-//****************************************************************************************************************************************************
-/// \return The delay to apply before sending automatically generated events.
-//****************************************************************************************************************************************************
-qint32 SettingsTab::eventDelayMs() const {
- return ui_.spinEventDelay->value();
-}
-
-
//****************************************************************************************************************************************************
/// \return The path
//****************************************************************************************************************************************************
@@ -319,14 +276,6 @@ void SettingsTab::exportTLSCertificates(QString const &folderPath) {
}
-//****************************************************************************************************************************************************
-/// \return The state of the check box.
-//****************************************************************************************************************************************************
-SettingsTab::BugReportResult SettingsTab::nextBugReportResult() const {
- return BugReportResult(ui_.comboBugReportResult->currentIndex());
-}
-
-
//****************************************************************************************************************************************************
/// \return the state of the 'TLS Certificate is installed' check box.
//****************************************************************************************************************************************************
@@ -429,14 +378,6 @@ void SettingsTab::setIsDoHEnabled(bool enabled) {
}
-//****************************************************************************************************************************************************
-/// \return The reply for the next IsPortFree gRPC call.
-//****************************************************************************************************************************************************
-bool SettingsTab::isPortFree() const {
- return ui_.checkIsPortFree->isChecked();
-}
-
-
//****************************************************************************************************************************************************
/// \param[in] path The path of the local cache.
//****************************************************************************************************************************************************
@@ -453,14 +394,6 @@ QString SettingsTab::diskCachePath() const {
}
-//****************************************************************************************************************************************************
-/// \return The value for the 'Next Cache Change Will Succeed' check box.
-//****************************************************************************************************************************************************
-bool SettingsTab::nextCacheChangeWillSucceed() const {
- return ui_.checkNextCacheChangeWillSucceed->isChecked();
-}
-
-
//****************************************************************************************************************************************************
/// \return the value for the 'Automatic Update' check.
//****************************************************************************************************************************************************
@@ -521,19 +454,16 @@ void SettingsTab::resetUI() {
ui_.editAddress->setText(QString());
ui_.editDescription->setPlainText(QString());
ui_.labelIncludeLogsValue->setText(QString());
- ui_.comboBugReportResult->setCurrentIndex(0);
ui_.editHostname->setText("localhost");
ui_.spinPortIMAP->setValue(1143);
ui_.spinPortSMTP->setValue(1025);
ui_.checkUseSSLForSMTP->setChecked(false);
ui_.checkDoHEnabled->setChecked(true);
- ui_.checkIsPortFree->setChecked(true);
QString const cacheDir = QDir(tmpDir).absoluteFilePath("cache");
QDir().mkpath(cacheDir);
ui_.editDiskCachePath->setText(QDir::toNativeSeparators(cacheDir));
- ui_.checkNextCacheChangeWillSucceed->setChecked(true);
ui_.checkAutomaticUpdate->setChecked(true);
diff --git a/internal/frontend/bridge-gui/bridge-gui-tester/Tabs/SettingsTab.h b/internal/frontend/bridge-gui/bridge-gui-tester/Tabs/SettingsTab.h
index edeb5ae8..8bed7a62 100644
--- a/internal/frontend/bridge-gui/bridge-gui-tester/Tabs/SettingsTab.h
+++ b/internal/frontend/bridge-gui/bridge-gui-tester/Tabs/SettingsTab.h
@@ -35,12 +35,6 @@ public: // data types.
Failure = 2
}; ///< Enumeration for the result of a TLS certificate installation.
- enum class BugReportResult {
- Success = 0,
- Error = 1,
- DataSharingError = 2,
- }; ///< Enumeration for the result of bug report sending
-
public: // member functions.
explicit SettingsTab(QWidget *parent = nullptr); ///< Default constructor.
SettingsTab(SettingsTab const &) = delete; ///< Disabled copy-constructor.
@@ -60,13 +54,11 @@ public: // member functions.
bool isAllMailVisible() const; ///< Get the value for the 'All Mail Visible' check.
bool isTelemetryDisabled() const; ///< Get the value for the 'Disable Telemetry' check box.
QString colorSchemeName() const; ///< Get the value of the 'Use Dark Theme' checkbox.
- qint32 eventDelayMs() const; ///< Get the delay for sending automatically generated events.
QString logsPath() const; ///< Get the content of the 'Logs Path' edit.
QString licensePath() const; ///< Get the content of the 'License Path' edit.
QString releaseNotesPageLink() const; ///< Get the content of the 'Release Notes Page Link' edit.
QString dependencyLicenseLink() const; ///< Get the content of the 'Dependency License Link' edit.
QString landingPageLink() const; ///< Get the content of the 'Landing Page Link' edit.
- BugReportResult nextBugReportResult() const; ///< Get the value of the 'Next bug report result' combo box.
bool isTLSCertificateInstalled() const; ///< Get the status of the 'TLS Certificate is installed' check box.
TLSCertInstallResult nextTLSCertInstallResult() const; ///< Get the value of the 'Next TLS Certificate install result' combo box.
bool nextTLSCertExportWillSucceed() const; ///< Get the status of the 'Next TLS Cert export will succeed' check box.
@@ -77,9 +69,7 @@ public: // member functions.
bool useSSLForSMTP() const; ///< Get the value for the 'Use SSL for SMTP' check box.
bool useSSLForIMAP() const; ///< Get the value for the 'Use SSL for IMAP' check box.
bool isDoHEnabled() const; ///< Get the value for the 'DoH Enabled' check box.
- bool isPortFree() const; ///< Get the value for the "Is Port Free" check box.
QString diskCachePath() const; ///< Get the value for the 'Disk Cache Path' edit.
- bool nextCacheChangeWillSucceed() const; ///< Get the value for the 'Next Cache Change will succeed' edit.
bool isAutomaticUpdateOn() const; ///
0
0
- 1160
- 777
+ 1146
+ 716
@@ -208,7 +208,7 @@
- 200
+ 0
0
@@ -749,328 +749,6 @@
- -
-
-
-
- 0
- 0
-
-
-
- Events && Errors
-
-
-
- 4
-
-
-
-
-
-
-
-
- Delay applied before sending automatically generated events
-
-
- Delay for asynchronous events
-
-
-
- -
-
-
- ms
-
-
- -1
-
-
- 3600000
-
-
- 100
-
-
- 0
-
-
-
- -
-
-
- Qt::Horizontal
-
-
-
- 40
- 1
-
-
-
-
-
-
- -
-
-
- -1
-
-
- 8
-
-
-
-
-
- Internet On
-
-
-
- -
-
-
- Show Main Window
-
-
-
- -
-
-
- Internet Off
-
-
-
- -
-
-
- API Certficate Issue
-
-
-
- -
-
-
- No Keychain
-
-
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
- Address related errors
-
-
-
-
-
-
-
-
-
- Address
-
-
-
- -
-
-
- dummy.user@proton.me
-
-
-
-
-
- -
-
-
-
-
-
- Address Changed
-
-
-
- -
-
-
- Address Changed Logout
-
-
-
-
-
-
-
-
- -
-
-
- Reply true to the next 'Is Port Free' request.
-
-
-
- -
-
-
- Next Cache Change will succeed
-
-
-
- -
-
-
-
-
-
- Next bug report result
-
-
-
- -
-
-
-
-
- Success
-
-
- -
-
- Error
-
-
- -
-
- Data sharing error
-
-
-
-
- -
-
-
- Qt::Horizontal
-
-
-
- 40
- 1
-
-
-
-
-
-
- -
-
-
- 8
-
-
-
-
-
- Update Manual Ready
-
-
-
- -
-
-
- 4.0
-
-
-
- -
-
-
- Update version changed
-
-
-
- -
-
-
- Update Force
-
-
-
- -
-
-
- Update manual restart
-
-
-
- -
-
-
- Update check finished
-
-
-
- -
-
-
- Update silent restart
-
-
-
- -
-
-
- QComboBox::AdjustToContents
-
-
-
-
- Update manual error
-
-
- -
-
- Update force error
-
-
- -
-
- Update silent error
-
-
-
-
- -
-
-
- Update error
-
-
-
- -
-
-
- Update is latest
-
-
-
- -
-
-
- Qt::Horizontal
-
-
-
- 40
- 1
-
-
-
-
-
-
-
-
-
@@ -1096,8 +774,6 @@
editDiskCachePath
editOSVersion
editEmailClient
- spinEventDelay
- checkIsPortFree