Other: C++ Code reformat.

This commit is contained in:
Xavier Michelon
2023-01-05 08:37:38 +01:00
parent bb07138fb0
commit 8790d3cfcf
58 changed files with 1348 additions and 1692 deletions

View File

@ -30,8 +30,7 @@ using namespace bridgepp;
//****************************************************************************************************************************************************
/// \return A reference to the application controller.
//****************************************************************************************************************************************************
AppController &app()
{
AppController &app() {
static AppController app;
return app;
}
@ -43,8 +42,7 @@ AppController &app()
AppController::AppController()
: log_(std::make_unique<Log>())
, bridgeGUILog_(std::make_unique<Log>())
, grpc_(std::make_unique<GRPCService>())
{
, grpc_(std::make_unique<GRPCService>()) {
}
@ -61,8 +59,7 @@ AppController::~AppController() // NOLINT(modernize-use-equals-default): impleme
//****************************************************************************************************************************************************
/// \param[in] mainWindow The main window.
//****************************************************************************************************************************************************
void AppController::setMainWindow(MainWindow *mainWindow)
{
void AppController::setMainWindow(MainWindow *mainWindow) {
mainWindow_ = mainWindow;
grpc_->connectProxySignals();
}
@ -71,10 +68,10 @@ void AppController::setMainWindow(MainWindow *mainWindow)
//****************************************************************************************************************************************************
/// \return The main window.
//****************************************************************************************************************************************************
MainWindow &AppController::mainWindow()
{
if (!mainWindow_)
MainWindow &AppController::mainWindow() {
if (!mainWindow_) {
throw Exception("mainWindow has not yet been registered.");
}
return *mainWindow_;
}
@ -82,8 +79,7 @@ MainWindow &AppController::mainWindow()
//****************************************************************************************************************************************************
/// \return A reference to the log.
//****************************************************************************************************************************************************
bridgepp::Log &AppController::log()
{
bridgepp::Log &AppController::log() {
return *log_;
}
@ -91,8 +87,7 @@ bridgepp::Log &AppController::log()
//****************************************************************************************************************************************************
/// \return A reference to the bridge-gui log.
//****************************************************************************************************************************************************
bridgepp::Log &AppController::bridgeGUILog()
{
bridgepp::Log &AppController::bridgeGUILog() {
return *bridgeGUILog_;
}
@ -100,7 +95,6 @@ bridgepp::Log &AppController::bridgeGUILog()
//****************************************************************************************************************************************************
/// \return A reference to the gRPC service.
//****************************************************************************************************************************************************
GRPCService &AppController::grpc()
{
GRPCService &AppController::grpc() {
return *grpc_;
}

View File

@ -21,6 +21,8 @@
class MainWindow;
class GRPCService;
namespace grpc { class StreamEvent; }
namespace bridgepp { class Log; }
@ -29,8 +31,7 @@ namespace bridgepp { class Log; }
//**********************************************************************************************************************
/// \brief Application controller class
//**********************************************************************************************************************
class AppController : public QObject
{
class AppController : public QObject {
Q_OBJECT
public: // member functions.
friend AppController &app();

View File

@ -29,8 +29,7 @@ using namespace grpc;
/// \param[in] The server token expected from gRPC calls
//****************************************************************************************************************************************************
GRPCMetadataProcessor::GRPCMetadataProcessor(QString const &serverToken)
: serverToken_(serverToken.toStdString())
{
: serverToken_(serverToken.toStdString()) {
}
@ -38,8 +37,7 @@ GRPCMetadataProcessor::GRPCMetadataProcessor(QString const &serverToken)
//****************************************************************************************************************************************************
/// \return false.
//****************************************************************************************************************************************************
bool GRPCMetadataProcessor::IsBlocking() const
{
bool GRPCMetadataProcessor::IsBlocking() const {
return false;
}
@ -49,28 +47,28 @@ bool GRPCMetadataProcessor::IsBlocking() const
/// \return the result of the metadata processing.
//****************************************************************************************************************************************************
Status GRPCMetadataProcessor::Process(AuthMetadataProcessor::InputMetadata const &auth_metadata, AuthContext *,
AuthMetadataProcessor::OutputMetadata *, AuthMetadataProcessor::OutputMetadata *)
{
try
{
AuthMetadataProcessor::OutputMetadata *, AuthMetadataProcessor::OutputMetadata *) {
try {
AuthMetadataProcessor::InputMetadata::const_iterator pathIt = auth_metadata.find(":path");
QString const callName = (pathIt == auth_metadata.end()) ? ("unkown gRPC call") : QString::fromLocal8Bit(pathIt->second);
AuthMetadataProcessor::InputMetadata::size_type const count = auth_metadata.count(grpcMetadataServerTokenKey);
if (count == 0)
if (count == 0) {
throw Exception(QString("Missing server token in gRPC client call '%1'.").arg(callName));
}
if (count > 1)
if (count > 1) {
throw Exception(QString("Several server tokens were provided in gRPC client call '%1'.").arg(callName));
}
if (auth_metadata.find(grpcMetadataServerTokenKey)->second != serverToken_)
if (auth_metadata.find(grpcMetadataServerTokenKey)->second != serverToken_) {
throw Exception(QString("Invalid server token provided by gRPC client call '%1'.").arg(callName));
}
app().log().trace(QString("Server token for gRPC call '%1' was validated.").arg(callName));
return Status::OK;
}
catch (Exception const &e)
{
catch (Exception const &e) {
app().log().error(e.qwhat());
return Status(StatusCode::UNAUTHENTICATED, e.qwhat().toStdString());
}

View File

@ -26,15 +26,14 @@
//****************************************************************************************************************************************************
/// \brief Metadata processor class in charge of checking the server token provided by client calls and stream requests.
//****************************************************************************************************************************************************
class GRPCMetadataProcessor: public grpc::AuthMetadataProcessor
{
class GRPCMetadataProcessor : public grpc::AuthMetadataProcessor {
public: // member functions.
GRPCMetadataProcessor(QString const &serverToken); ///< Default constructor.
GRPCMetadataProcessor(GRPCMetadataProcessor const&) = delete; ///< Disabled copy-constructor.
GRPCMetadataProcessor(GRPCMetadataProcessor&&) = delete; ///< Disabled assignment copy-constructor.
GRPCMetadataProcessor(GRPCMetadataProcessor const &) = delete; ///< Disabled copy-constructor.
GRPCMetadataProcessor(GRPCMetadataProcessor &&) = delete; ///< Disabled assignment copy-constructor.
~GRPCMetadataProcessor() = default; ///< Destructor.
GRPCMetadataProcessor& operator=(GRPCMetadataProcessor const&) = delete; ///< Disabled assignment operator.
GRPCMetadataProcessor& operator=(GRPCMetadataProcessor&&) = delete; ///< Disabled move assignment operator.
GRPCMetadataProcessor &operator=(GRPCMetadataProcessor const &) = delete; ///< Disabled assignment operator.
GRPCMetadataProcessor &operator=(GRPCMetadataProcessor &&) = delete; ///< Disabled move assignment operator.
bool IsBlocking() const override; ///< Is the processor blocking?
grpc::Status Process(InputMetadata const &auth_metadata, grpc::AuthContext *context, OutputMetadata *consumed_auth_metadata,
OutputMetadata *response_metadata) override; ///< Process the metadata

View File

@ -24,15 +24,14 @@
//
//****************************************************************************************************************************************************
GRPCQtProxy::GRPCQtProxy()
: QObject(nullptr)
{
: QObject(nullptr) {
}
//****************************************************************************************************************************************************
//
//****************************************************************************************************************************************************
void GRPCQtProxy::connectSignals()
{
void GRPCQtProxy::connectSignals() {
MainWindow &mainWindow = app().mainWindow();
SettingsTab &settingsTab = mainWindow.settingsTab();
UsersTab &usersTab = mainWindow.usersTab();
@ -60,8 +59,7 @@ void GRPCQtProxy::connectSignals()
//****************************************************************************************************************************************************
/// \param[in] event The event.
//****************************************************************************************************************************************************
void GRPCQtProxy::sendDelayedEvent(bridgepp::SPStreamEvent const &event)
{
void GRPCQtProxy::sendDelayedEvent(bridgepp::SPStreamEvent const &event) {
emit delayedEventRequested(event);
}
@ -69,8 +67,7 @@ void GRPCQtProxy::sendDelayedEvent(bridgepp::SPStreamEvent const &event)
//****************************************************************************************************************************************************
/// \param[in] on The value.
//****************************************************************************************************************************************************
void GRPCQtProxy::setIsAutostartOn(bool on)
{
void GRPCQtProxy::setIsAutostartOn(bool on) {
emit setIsAutostartOnReceived(on);
}
@ -78,8 +75,7 @@ void GRPCQtProxy::setIsAutostartOn(bool on)
//****************************************************************************************************************************************************
/// \param[in] enabled The value.
//****************************************************************************************************************************************************
void GRPCQtProxy::setIsBetaEnabled(bool enabled)
{
void GRPCQtProxy::setIsBetaEnabled(bool enabled) {
emit setIsBetaEnabledReceived(enabled);
}
@ -87,8 +83,7 @@ void GRPCQtProxy::setIsBetaEnabled(bool enabled)
//****************************************************************************************************************************************************
/// \param[in] visible The value.
//****************************************************************************************************************************************************
void GRPCQtProxy::setIsAllMailVisible(bool visible)
{
void GRPCQtProxy::setIsAllMailVisible(bool visible) {
emit setIsAllMailVisibleReceived(visible);
}
@ -96,8 +91,7 @@ void GRPCQtProxy::setIsAllMailVisible(bool visible)
//****************************************************************************************************************************************************
/// \param[in] name The color scheme.
//****************************************************************************************************************************************************
void GRPCQtProxy::setColorSchemeName(QString const &name)
{
void GRPCQtProxy::setColorSchemeName(QString const &name) {
emit setColorSchemeNameReceived(name);
}
@ -111,8 +105,7 @@ void GRPCQtProxy::setColorSchemeName(QString const &name)
/// \param[in] includeLogs Should the logs be included.
//****************************************************************************************************************************************************
void GRPCQtProxy::reportBug(QString const &osType, QString const &osVersion, QString const &emailClient, QString const &address,
QString const &description, bool includeLogs)
{
QString const &description, bool includeLogs) {
emit reportBugReceived(osType, osVersion, emailClient, address, description, includeLogs);
}
@ -120,8 +113,7 @@ void GRPCQtProxy::reportBug(QString const &osType, QString const &osVersion, QSt
//****************************************************************************************************************************************************
/// \param[in] folderPath The folder path.
//****************************************************************************************************************************************************
void GRPCQtProxy::exportTLSCertificates(QString const &folderPath)
{
void GRPCQtProxy::exportTLSCertificates(QString const &folderPath) {
emit exportTLSCertificatesReceived(folderPath);
}
@ -129,8 +121,7 @@ void GRPCQtProxy::exportTLSCertificates(QString const &folderPath)
//****************************************************************************************************************************************************
/// \param[in] isStreaming Is the gRPC server streaming.
//****************************************************************************************************************************************************
void GRPCQtProxy::setIsStreaming(bool isStreaming)
{
void GRPCQtProxy::setIsStreaming(bool isStreaming) {
emit setIsStreamingReceived(isStreaming);
}
@ -138,8 +129,7 @@ void GRPCQtProxy::setIsStreaming(bool isStreaming)
//****************************************************************************************************************************************************
/// \param[in] clientPlatform The client platform.
//****************************************************************************************************************************************************
void GRPCQtProxy::setClientPlatform(QString const &clientPlatform)
{
void GRPCQtProxy::setClientPlatform(QString const &clientPlatform) {
emit setClientPlatformReceived(clientPlatform);
}
@ -150,8 +140,7 @@ void GRPCQtProxy::setClientPlatform(QString const &clientPlatform)
/// \param[in] useSSLForIMAP The IMAP connexion mode.
/// \param[in] useSSLForSMTP The IMAP connexion mode.
//****************************************************************************************************************************************************
void GRPCQtProxy::setMailServerSettings(qint32 imapPort, qint32 smtpPort, bool useSSLForIMAP, bool userSSLForSMTP)
{
void GRPCQtProxy::setMailServerSettings(qint32 imapPort, qint32 smtpPort, bool useSSLForIMAP, bool userSSLForSMTP) {
emit setMailServerSettingsReceived(imapPort, smtpPort, useSSLForIMAP, userSSLForSMTP);
}
@ -159,8 +148,7 @@ void GRPCQtProxy::setMailServerSettings(qint32 imapPort, qint32 smtpPort, bool u
//****************************************************************************************************************************************************
/// \param[in] enabled Is DoH enabled?
//****************************************************************************************************************************************************
void GRPCQtProxy::setIsDoHEnabled(bool enabled)
{
void GRPCQtProxy::setIsDoHEnabled(bool enabled) {
emit setIsDoHEnabledReceived(enabled);
}
@ -168,8 +156,7 @@ void GRPCQtProxy::setIsDoHEnabled(bool enabled)
//****************************************************************************************************************************************************
/// \param[in] path The disk cache path.
//****************************************************************************************************************************************************
void GRPCQtProxy::setDiskCachePath(QString const &path)
{
void GRPCQtProxy::setDiskCachePath(QString const &path) {
emit setDiskCachePathReceived(path);
}
@ -177,8 +164,7 @@ void GRPCQtProxy::setDiskCachePath(QString const &path)
//****************************************************************************************************************************************************
/// \param[in] on Is automatic update on?
//****************************************************************************************************************************************************
void GRPCQtProxy::setIsAutomaticUpdateOn(bool on)
{
void GRPCQtProxy::setIsAutomaticUpdateOn(bool on) {
emit setIsAutomaticUpdateOnReceived(on);
}
@ -187,8 +173,7 @@ void GRPCQtProxy::setIsAutomaticUpdateOn(bool on)
/// \param[in] userID The userID.
/// \param[in] makeItActive Should split mode be active.
//****************************************************************************************************************************************************
void GRPCQtProxy::setUserSplitMode(QString const &userID, bool makeItActive)
{
void GRPCQtProxy::setUserSplitMode(QString const &userID, bool makeItActive) {
emit setUserSplitModeReceived(userID, makeItActive);
}
@ -196,8 +181,7 @@ void GRPCQtProxy::setUserSplitMode(QString const &userID, bool makeItActive)
//****************************************************************************************************************************************************
/// \param[in] userID The userID.
//****************************************************************************************************************************************************
void GRPCQtProxy::logoutUser(QString const &userID)
{
void GRPCQtProxy::logoutUser(QString const &userID) {
emit logoutUserReceived(userID);
}
@ -205,8 +189,7 @@ void GRPCQtProxy::logoutUser(QString const &userID)
//****************************************************************************************************************************************************
/// \param[in] userID The userID.
//****************************************************************************************************************************************************
void GRPCQtProxy::removeUser(QString const &userID)
{
void GRPCQtProxy::removeUser(QString const &userID) {
emit removeUserReceived(userID);
}
@ -215,7 +198,6 @@ void GRPCQtProxy::removeUser(QString const &userID)
/// \param[in] userID The userID.
/// \param[in] address The address.
//****************************************************************************************************************************************************
void GRPCQtProxy::configureUserAppleMail(QString const &userID, QString const &address)
{
void GRPCQtProxy::configureUserAppleMail(QString const &userID, QString const &address) {
emit configureUserAppleMailReceived(userID, address);
}

View File

@ -26,8 +26,7 @@
//****************************************************************************************************************************************************
/// \brief Proxy object used by the gRPC service (which does not inherit QObject) to use the Qt Signal/Slot system.
//****************************************************************************************************************************************************
class GRPCQtProxy : public QObject
{
class GRPCQtProxy : public QObject {
Q_OBJECT
public: // member functions.
GRPCQtProxy(); ///< Default constructor.

View File

@ -32,8 +32,7 @@ using namespace grpc;
//
//****************************************************************************************************************************************************
GRPCServerWorker::GRPCServerWorker(QObject *parent)
: Worker(parent)
{
: Worker(parent) {
}
@ -41,19 +40,17 @@ GRPCServerWorker::GRPCServerWorker(QObject *parent)
//****************************************************************************************************************************************************
//
//****************************************************************************************************************************************************
void GRPCServerWorker::run()
{
try
{
void GRPCServerWorker::run() {
try {
emit started();
SslServerCredentialsOptions::PemKeyCertPair pair;
pair.private_key = testTLSKey.toStdString();
pair.cert_chain = testTLSCert.toStdString();
SslServerCredentialsOptions ssl_opts;
ssl_opts.pem_root_certs="";
ssl_opts.pem_root_certs = "";
ssl_opts.pem_key_cert_pairs.push_back(pair);
std::shared_ptr<ServerCredentials> credentials = grpc::SslServerCredentials(ssl_opts);
std::shared_ptr<ServerCredentials> credentials = grpc::SslServerCredentials(ssl_opts);
GRPCConfig config;
config.cert = testTLSCert;
@ -65,8 +62,9 @@ void GRPCServerWorker::run()
bool const useFileSocket = useFileSocketForGRPC();
if (useFileSocket) {
QString const fileSocketPath = getAvailableFileSocketPath();
if (fileSocketPath.isEmpty())
if (fileSocketPath.isEmpty()) {
throw Exception("Could not get an available file socket.");
}
builder.AddListeningPort(QString("unix://%1").arg(fileSocketPath).toStdString(), credentials);
config.fileSocketPath = fileSocketPath;
} else {
@ -76,23 +74,25 @@ void GRPCServerWorker::run()
builder.RegisterService(&app().grpc());
server_ = builder.BuildAndStart();
if (!server_)
if (!server_) {
throw Exception("Could not create gRPC server.");
}
app().log().debug("gRPC Server started.");
config.port = port;
QString err;
if (!config.save(grpcServerConfigPath(), &err))
if (!config.save(grpcServerConfigPath(), &err)) {
throw Exception(QString("Could not save gRPC server config. %1").arg(err));
}
server_->Wait();
emit finished();
app().log().debug("gRPC Server exited.");
}
catch (Exception const &e)
{
if (server_)
catch (Exception const &e) {
if (server_) {
server_->Shutdown();
}
emit error(e.qwhat());
}
@ -102,10 +102,10 @@ void GRPCServerWorker::run()
//****************************************************************************************************************************************************
//
//****************************************************************************************************************************************************
void GRPCServerWorker::stop()
{
if (server_)
void GRPCServerWorker::stop() {
if (server_) {
server_->Shutdown();
}
}

View File

@ -29,8 +29,7 @@
//**********************************************************************************************************************
/// \brief gRPC server worker
//**********************************************************************************************************************
class GRPCServerWorker : public bridgepp::Worker
{
class GRPCServerWorker : public bridgepp::Worker {
Q_OBJECT
public: // member functions.
explicit GRPCServerWorker(QObject *parent); ///< Default constructor.

View File

@ -27,8 +27,7 @@ using namespace grpc;
using namespace google::protobuf;
using namespace bridgepp;
namespace
{
namespace {
QString const defaultKeychain = "defaultKeychain"; ///< The default keychain.
@ -40,8 +39,7 @@ QString const defaultKeychain = "defaultKeychain"; ///< The default keychain.
//****************************************************************************************************************************************************
//
//****************************************************************************************************************************************************
void GRPCService::connectProxySignals()
{
void GRPCService::connectProxySignals() {
qtProxy_.connectSignals();
}
@ -49,8 +47,7 @@ void GRPCService::connectProxySignals()
//****************************************************************************************************************************************************
/// \return true iff the service is streaming events.
//****************************************************************************************************************************************************
bool GRPCService::isStreaming() const
{
bool GRPCService::isStreaming() const {
QMutexLocker locker(&eventStreamMutex_);
return isStreaming_;
}
@ -60,14 +57,12 @@ bool GRPCService::isStreaming() const
/// \param[in] request The request.
/// \param[out] response The response.
//****************************************************************************************************************************************************
Status GRPCService::CheckTokens(::grpc::ServerContext *, ::google::protobuf::StringValue const *request, ::google::protobuf::StringValue *response)
{
Log& log = app().log();
Status GRPCService::CheckTokens(::grpc::ServerContext *, ::google::protobuf::StringValue const *request, ::google::protobuf::StringValue *response) {
Log &log = app().log();
log.debug(__FUNCTION__);
GRPCConfig config;
QString error;
if (!config.load(QString::fromStdString(request->value()), &error))
{
if (!config.load(QString::fromStdString(request->value()), &error)) {
QString const err = "Could not load gRPC client config";
log.error(err);
return grpc::Status(StatusCode::UNAUTHENTICATED, err.toStdString());
@ -82,8 +77,7 @@ Status GRPCService::CheckTokens(::grpc::ServerContext *, ::google::protobuf::Str
/// \param[in] request the request.
/// \return The status for the call.
//****************************************************************************************************************************************************
Status GRPCService::AddLogEntry(ServerContext *, AddLogEntryRequest const *request, Empty *)
{
Status GRPCService::AddLogEntry(ServerContext *, AddLogEntryRequest const *request, Empty *) {
app().bridgeGUILog().addEntry(logLevelFromGRPC(request->level()), QString::fromStdString(request->message()));
return Status::OK;
}
@ -92,8 +86,7 @@ Status GRPCService::AddLogEntry(ServerContext *, AddLogEntryRequest const *reque
//****************************************************************************************************************************************************
/// \return The status for the call.
//****************************************************************************************************************************************************
Status GRPCService::GuiReady(ServerContext *, Empty const *, Empty *)
{
Status GRPCService::GuiReady(ServerContext *, Empty const *, Empty *) {
app().log().debug(__FUNCTION__);
app().mainWindow().settingsTab().setGUIReady(true);
return Status::OK;
@ -103,8 +96,7 @@ Status GRPCService::GuiReady(ServerContext *, Empty const *, Empty *)
//****************************************************************************************************************************************************
/// \return The status for the call.
//****************************************************************************************************************************************************
Status GRPCService::Quit(ServerContext *, Empty const *, Empty *)
{
Status GRPCService::Quit(ServerContext *, Empty const *, Empty *) {
// We do not actually quit.
app().log().debug(__FUNCTION__);
return Status::OK;
@ -114,8 +106,7 @@ Status GRPCService::Quit(ServerContext *, Empty const *, Empty *)
//****************************************************************************************************************************************************
/// \return The status for the call.
//****************************************************************************************************************************************************
Status GRPCService::Restart(ServerContext *, Empty const *, Empty *)
{
Status GRPCService::Restart(ServerContext *, Empty const *, Empty *) {
// we do not actually restart.
app().log().debug(__FUNCTION__);
return Status::OK;
@ -126,8 +117,7 @@ Status GRPCService::Restart(ServerContext *, Empty const *, Empty *)
/// \param[out] response The response.
/// \return The status for the call.
//****************************************************************************************************************************************************
Status GRPCService::ShowOnStartup(ServerContext *, Empty const *, BoolValue *response)
{
Status GRPCService::ShowOnStartup(ServerContext *, Empty const *, BoolValue *response) {
app().log().debug(__FUNCTION__);
response->set_value(app().mainWindow().settingsTab().showOnStartup());
return Status::OK;
@ -138,8 +128,7 @@ Status GRPCService::ShowOnStartup(ServerContext *, Empty const *, BoolValue *res
/// \param[out] response The response.
/// \return The status for the call.
//****************************************************************************************************************************************************
Status GRPCService::ShowSplashScreen(ServerContext *, Empty const *, BoolValue *response)
{
Status GRPCService::ShowSplashScreen(ServerContext *, Empty const *, BoolValue *response) {
app().log().debug(__FUNCTION__);
response->set_value(app().mainWindow().settingsTab().showSplashScreen());
return Status::OK;
@ -150,8 +139,7 @@ Status GRPCService::ShowSplashScreen(ServerContext *, Empty const *, BoolValue *
/// \param[out] response The response.
/// \return The status for the call.
//****************************************************************************************************************************************************
Status GRPCService::IsFirstGuiStart(ServerContext *, Empty const *, BoolValue *response)
{
Status GRPCService::IsFirstGuiStart(ServerContext *, Empty const *, BoolValue *response) {
app().log().debug(__FUNCTION__);
response->set_value(app().mainWindow().settingsTab().isFirstGUIStart());
return Status::OK;
@ -162,8 +150,7 @@ Status GRPCService::IsFirstGuiStart(ServerContext *, Empty const *, BoolValue *r
/// \param[in] request The request.
/// \return The status for the call.
//****************************************************************************************************************************************************
Status GRPCService::SetIsAutostartOn(ServerContext *, BoolValue const *request, Empty *)
{
Status GRPCService::SetIsAutostartOn(ServerContext *, BoolValue const *request, Empty *) {
app().log().debug(__FUNCTION__);
app().mainWindow().settingsTab().setIsAutostartOn(request->value());
qtProxy_.sendDelayedEvent(newToggleAutostartFinishedEvent());
@ -175,8 +162,7 @@ Status GRPCService::SetIsAutostartOn(ServerContext *, BoolValue const *request,
/// \param[out] response The response.
/// \return The status for the call.
//****************************************************************************************************************************************************
Status GRPCService::IsAutostartOn(ServerContext *, Empty const *, BoolValue *response)
{
Status GRPCService::IsAutostartOn(ServerContext *, Empty const *, BoolValue *response) {
app().log().debug(__FUNCTION__);
response->set_value(app().mainWindow().settingsTab().isAutostartOn());
return Status::OK;
@ -187,8 +173,7 @@ Status GRPCService::IsAutostartOn(ServerContext *, Empty const *, BoolValue *res
/// \param[in] request The request.
/// \return The status for the call.
//****************************************************************************************************************************************************
Status GRPCService::SetIsBetaEnabled(ServerContext *, BoolValue const *request, Empty *)
{
Status GRPCService::SetIsBetaEnabled(ServerContext *, BoolValue const *request, Empty *) {
app().log().debug(__FUNCTION__);
qtProxy_.setIsBetaEnabled(request->value());
return Status::OK;
@ -199,8 +184,7 @@ Status GRPCService::SetIsBetaEnabled(ServerContext *, BoolValue const *request,
/// \param[out] response The response.
/// \return The status for the call.
//****************************************************************************************************************************************************
Status GRPCService::IsBetaEnabled(ServerContext *, Empty const *, BoolValue *response)
{
Status GRPCService::IsBetaEnabled(ServerContext *, Empty const *, BoolValue *response) {
app().log().debug(__FUNCTION__);
response->set_value(app().mainWindow().settingsTab().isBetaEnabled());
return Status::OK;
@ -211,8 +195,7 @@ Status GRPCService::IsBetaEnabled(ServerContext *, Empty const *, BoolValue *res
/// \param[in] request The request.
/// \return The status for the call.
//****************************************************************************************************************************************************
Status GRPCService::SetIsAllMailVisible(ServerContext *, BoolValue const *request, Empty *)
{
Status GRPCService::SetIsAllMailVisible(ServerContext *, BoolValue const *request, Empty *) {
app().log().debug(__FUNCTION__);
qtProxy_.setIsAllMailVisible(request->value());
return Status::OK;
@ -223,8 +206,7 @@ Status GRPCService::SetIsAllMailVisible(ServerContext *, BoolValue const *reques
/// \param[out] response The response.
/// \return The status for the call.
//****************************************************************************************************************************************************
Status GRPCService::IsAllMailVisible(ServerContext *, Empty const *request, BoolValue *response)
{
Status GRPCService::IsAllMailVisible(ServerContext *, Empty const *request, BoolValue *response) {
app().log().debug(__FUNCTION__);
response->set_value(app().mainWindow().settingsTab().isAllMailVisible());
return Status::OK;
@ -235,8 +217,7 @@ Status GRPCService::IsAllMailVisible(ServerContext *, Empty const *request, Bool
/// \param[out] response The response.
/// \return The status for the call.
//****************************************************************************************************************************************************
Status GRPCService::GoOs(ServerContext *, Empty const *, StringValue *response)
{
Status GRPCService::GoOs(ServerContext *, Empty const *, StringValue *response) {
app().log().debug(__FUNCTION__);
response->set_value(app().mainWindow().settingsTab().os().toStdString());
return Status::OK;
@ -246,8 +227,7 @@ Status GRPCService::GoOs(ServerContext *, Empty const *, StringValue *response)
//****************************************************************************************************************************************************
/// \return The status for the call.
//****************************************************************************************************************************************************
Status GRPCService::TriggerReset(ServerContext *, Empty const *, Empty *)
{
Status GRPCService::TriggerReset(ServerContext *, Empty const *, Empty *) {
app().log().debug(__FUNCTION__);
app().log().info("Bridge GUI requested a reset");
return Status::OK;
@ -258,8 +238,7 @@ Status GRPCService::TriggerReset(ServerContext *, Empty const *, Empty *)
/// \param[out] response The response.
/// \return The status for the call.
//****************************************************************************************************************************************************
grpc::Status GRPCService::Version(ServerContext *, Empty const *, StringValue *response)
{
grpc::Status GRPCService::Version(ServerContext *, Empty const *, StringValue *response) {
app().log().debug(__FUNCTION__);
response->set_value(app().mainWindow().settingsTab().bridgeVersion().toStdString());
return Status::OK;
@ -270,8 +249,7 @@ grpc::Status GRPCService::Version(ServerContext *, Empty const *, StringValue *r
/// \param[out] response The response.
/// \return The status for the call.
//****************************************************************************************************************************************************
Status GRPCService::LogsPath(ServerContext *, Empty const *, StringValue *response)
{
Status GRPCService::LogsPath(ServerContext *, Empty const *, StringValue *response) {
app().log().debug(__FUNCTION__);
response->set_value(app().mainWindow().settingsTab().logsPath().toStdString());
return Status::OK;
@ -282,8 +260,7 @@ Status GRPCService::LogsPath(ServerContext *, Empty const *, StringValue *respon
/// \param[out] response The response.
/// \return The status for the call.
//****************************************************************************************************************************************************
Status GRPCService::LicensePath(ServerContext *, Empty const *, StringValue *response)
{
Status GRPCService::LicensePath(ServerContext *, Empty const *, StringValue *response) {
app().log().debug(__FUNCTION__);
response->set_value(app().mainWindow().settingsTab().licensePath().toStdString());
return Status::OK;
@ -294,8 +271,7 @@ Status GRPCService::LicensePath(ServerContext *, Empty const *, StringValue *res
/// \param[out] response The response.
/// \return The status for the call.
//****************************************************************************************************************************************************
Status GRPCService::ReleaseNotesPageLink(ServerContext *, Empty const *, StringValue *response)
{
Status GRPCService::ReleaseNotesPageLink(ServerContext *, Empty const *, StringValue *response) {
app().log().debug(__FUNCTION__);
response->set_value(app().mainWindow().settingsTab().releaseNotesPageLink().toStdString());
return Status::OK;
@ -306,8 +282,7 @@ Status GRPCService::ReleaseNotesPageLink(ServerContext *, Empty const *, StringV
/// \param[out] response The response.
/// \return The status for the call.
//****************************************************************************************************************************************************
Status GRPCService::DependencyLicensesLink(ServerContext *, Empty const *, StringValue *response)
{
Status GRPCService::DependencyLicensesLink(ServerContext *, Empty const *, StringValue *response) {
app().log().debug(__FUNCTION__);
response->set_value(app().mainWindow().settingsTab().dependencyLicenseLink().toStdString());
return Status::OK;
@ -318,8 +293,7 @@ Status GRPCService::DependencyLicensesLink(ServerContext *, Empty const *, Strin
/// \param[out] response The response.
/// \return The status for the call.
//****************************************************************************************************************************************************
Status GRPCService::LandingPageLink(ServerContext *, Empty const *, StringValue *response)
{
Status GRPCService::LandingPageLink(ServerContext *, Empty const *, StringValue *response) {
app().log().debug(__FUNCTION__);
response->set_value(app().mainWindow().settingsTab().landingPageLink().toStdString());
return Status::OK;
@ -330,8 +304,7 @@ Status GRPCService::LandingPageLink(ServerContext *, Empty const *, StringValue
/// \param[in] request The request.
/// \return The status for the call.
//****************************************************************************************************************************************************
Status GRPCService::SetColorSchemeName(ServerContext *, StringValue const *request, Empty *)
{
Status GRPCService::SetColorSchemeName(ServerContext *, StringValue const *request, Empty *) {
app().log().debug(__FUNCTION__);
qtProxy_.setColorSchemeName(QString::fromStdString(request->value()));
return Status::OK;
@ -342,8 +315,7 @@ Status GRPCService::SetColorSchemeName(ServerContext *, StringValue const *reque
/// \param[in] response The response.
/// \return The status for the call.
//****************************************************************************************************************************************************
Status GRPCService::ColorSchemeName(ServerContext *, Empty const *, StringValue *response)
{
Status GRPCService::ColorSchemeName(ServerContext *, Empty const *, StringValue *response) {
app().log().debug(__FUNCTION__);
response->set_value(app().mainWindow().settingsTab().colorSchemeName().toStdString());
return Status::OK;
@ -354,8 +326,7 @@ Status GRPCService::ColorSchemeName(ServerContext *, Empty const *, StringValue
/// \param[in] response The response.
/// \return The status for the call.
//****************************************************************************************************************************************************
Status GRPCService::CurrentEmailClient(ServerContext *, Empty const *, StringValue *response)
{
Status GRPCService::CurrentEmailClient(ServerContext *, Empty const *, StringValue *response) {
app().log().debug(__FUNCTION__);
response->set_value(app().mainWindow().settingsTab().currentEmailClient().toStdString());
return Status::OK;
@ -366,8 +337,7 @@ Status GRPCService::CurrentEmailClient(ServerContext *, Empty const *, StringVal
/// \param[in] request The request.
/// \return The status for the call.
//****************************************************************************************************************************************************
Status GRPCService::ForceLauncher(ServerContext *, StringValue const *request, Empty *)
{
Status GRPCService::ForceLauncher(ServerContext *, StringValue const *request, Empty *) {
app().log().debug(__FUNCTION__);
app().log().info(QString("ForceLauncher: %1").arg(QString::fromStdString(request->value())));
return Status::OK;
@ -378,20 +348,17 @@ Status GRPCService::ForceLauncher(ServerContext *, StringValue const *request, E
/// \param[in] request The request.
/// \return The status for the call.
//****************************************************************************************************************************************************
Status GRPCService::SetMainExecutable(ServerContext *, StringValue const *request, Empty *)
{
Status GRPCService::SetMainExecutable(ServerContext *, StringValue const *request, Empty *) {
app().log().debug(__FUNCTION__);
app().log().info(QString("SetMainExecutable: %1").arg(QString::fromStdString(request->value())));
return Status::OK;
}
//****************************************************************************************************************************************************
/// \param[in] request The request
//****************************************************************************************************************************************************
Status GRPCService::ReportBug(ServerContext *, ReportBugRequest const *request, Empty *)
{
Status GRPCService::ReportBug(ServerContext *, ReportBugRequest const *request, Empty *) {
app().log().debug(__FUNCTION__);
SettingsTab &tab = app().mainWindow().settingsTab();
qtProxy_.reportBug(QString::fromStdString(request->ostype()), QString::fromStdString(request->osversion()),
@ -407,13 +374,14 @@ Status GRPCService::ReportBug(ServerContext *, ReportBugRequest const *request,
//****************************************************************************************************************************************************
/// \param[in] request The request
//****************************************************************************************************************************************************
Status GRPCService::ExportTLSCertificates(ServerContext *, StringValue const *request, Empty *response)
{
Status GRPCService::ExportTLSCertificates(ServerContext *, StringValue const *request, Empty *response) {
SettingsTab &tab = app().mainWindow().settingsTab();
if (!tab.nextTLSCertExportWillSucceed())
if (!tab.nextTLSCertExportWillSucceed()) {
qtProxy_.sendDelayedEvent(newGenericErrorEvent(grpc::TLS_CERT_EXPORT_ERROR));
if (!tab.nextTLSKeyExportWillSucceed())
}
if (!tab.nextTLSKeyExportWillSucceed()) {
qtProxy_.sendDelayedEvent(newGenericErrorEvent(grpc::TLS_KEY_EXPORT_ERROR));
}
qtProxy_.exportTLSCertificates(QString::fromStdString(request->value()));
return Status::OK;
}
@ -423,28 +391,23 @@ Status GRPCService::ExportTLSCertificates(ServerContext *, StringValue const *re
/// \param[in] request The request.
/// \return The status for the call.
//****************************************************************************************************************************************************
Status GRPCService::Login(ServerContext *, LoginRequest const *request, Empty *)
{
Status GRPCService::Login(ServerContext *, LoginRequest const *request, Empty *) {
app().log().debug(__FUNCTION__);
UsersTab &usersTab = app().mainWindow().usersTab();
loginUsername_ = QString::fromStdString(request->username());
if (usersTab.nextUserUsernamePasswordError())
{
if (usersTab.nextUserUsernamePasswordError()) {
qtProxy_.sendDelayedEvent(newLoginError(LoginErrorType::USERNAME_PASSWORD_ERROR, usersTab.usernamePasswordErrorMessage()));
return Status::OK;
}
if (usersTab.nextUserFreeUserError())
{
if (usersTab.nextUserFreeUserError()) {
qtProxy_.sendDelayedEvent(newLoginError(LoginErrorType::FREE_USER, "Free user error."));
return Status::OK;
}
if (usersTab.nextUserTFARequired())
{
if (usersTab.nextUserTFARequired()) {
qtProxy_.sendDelayedEvent(newLoginTfaRequestedEvent(loginUsername_));
return Status::OK;
}
if (usersTab.nextUserTwoPasswordsRequired())
{
if (usersTab.nextUserTwoPasswordsRequired()) {
qtProxy_.sendDelayedEvent(newLoginTwoPasswordsRequestedEvent());
return Status::OK;
}
@ -454,8 +417,9 @@ Status GRPCService::Login(ServerContext *, LoginRequest const *request, Empty *)
user->setUsername(QString::fromStdString(request->username()));
usersTab.userTable().append(user);
if (usersTab.nextUserAlreadyLoggedIn())
if (usersTab.nextUserAlreadyLoggedIn()) {
qtProxy_.sendDelayedEvent(newLoginAlreadyLoggedInEvent(userID));
}
qtProxy_.sendDelayedEvent(newLoginFinishedEvent(userID));
return Status::OK;
}
@ -465,22 +429,18 @@ Status GRPCService::Login(ServerContext *, LoginRequest const *request, Empty *)
/// \param[in] request The request.
/// \return The status for the call.
//****************************************************************************************************************************************************
Status GRPCService::Login2FA(ServerContext *, LoginRequest const *request, Empty *)
{
Status GRPCService::Login2FA(ServerContext *, LoginRequest const *request, Empty *) {
app().log().debug(__FUNCTION__);
UsersTab &usersTab = app().mainWindow().usersTab();
if (usersTab.nextUserTFAError())
{
if (usersTab.nextUserTFAError()) {
qtProxy_.sendDelayedEvent(newLoginError(LoginErrorType::TFA_ERROR, "2FA Error."));
return Status::OK;
}
if (usersTab.nextUserTFAAbort())
{
if (usersTab.nextUserTFAAbort()) {
qtProxy_.sendDelayedEvent(newLoginError(LoginErrorType::TFA_ABORT, "2FA Abort."));
return Status::OK;
}
if (usersTab.nextUserTwoPasswordsRequired())
{
if (usersTab.nextUserTwoPasswordsRequired()) {
qtProxy_.sendDelayedEvent(newLoginTwoPasswordsRequestedEvent());
return Status::OK;
}
@ -490,8 +450,9 @@ Status GRPCService::Login2FA(ServerContext *, LoginRequest const *request, Empty
user->setUsername(QString::fromStdString(request->username()));
usersTab.userTable().append(user);
if (usersTab.nextUserAlreadyLoggedIn())
if (usersTab.nextUserAlreadyLoggedIn()) {
qtProxy_.sendDelayedEvent(newLoginAlreadyLoggedInEvent(userID));
}
qtProxy_.sendDelayedEvent(newLoginFinishedEvent(userID));
return Status::OK;
}
@ -501,19 +462,16 @@ Status GRPCService::Login2FA(ServerContext *, LoginRequest const *request, Empty
/// \param[in] request The request.
/// \return The status for the call.
//****************************************************************************************************************************************************
Status GRPCService::Login2Passwords(ServerContext *, LoginRequest const *request, Empty *)
{
Status GRPCService::Login2Passwords(ServerContext *, LoginRequest const *request, Empty *) {
app().log().debug(__FUNCTION__);
UsersTab &usersTab = app().mainWindow().usersTab();
if (usersTab.nextUserTwoPasswordsError())
{
if (usersTab.nextUserTwoPasswordsError()) {
qtProxy_.sendDelayedEvent(newLoginError(LoginErrorType::TWO_PASSWORDS_ERROR, "Two Passwords error."));
return Status::OK;
}
if (usersTab.nextUserTwoPasswordsAbort())
{
if (usersTab.nextUserTwoPasswordsAbort()) {
qtProxy_.sendDelayedEvent(newLoginError(LoginErrorType::TWO_PASSWORDS_ABORT, "Two Passwords abort."));
return Status::OK;
}
@ -523,8 +481,9 @@ Status GRPCService::Login2Passwords(ServerContext *, LoginRequest const *request
user->setUsername(QString::fromStdString(request->username()));
usersTab.userTable().append(user);
if (usersTab.nextUserAlreadyLoggedIn())
if (usersTab.nextUserAlreadyLoggedIn()) {
qtProxy_.sendDelayedEvent(newLoginAlreadyLoggedInEvent(userID));
}
qtProxy_.sendDelayedEvent(newLoginFinishedEvent(userID));
return Status::OK;
}
@ -534,8 +493,7 @@ Status GRPCService::Login2Passwords(ServerContext *, LoginRequest const *request
/// \param[in] request The request.
/// \return The status for the call.
//****************************************************************************************************************************************************
Status GRPCService::LoginAbort(ServerContext *, LoginAbortRequest const *request, Empty *)
{
Status GRPCService::LoginAbort(ServerContext *, LoginAbortRequest const *request, Empty *) {
app().log().debug(__FUNCTION__);
loginUsername_ = QString();
return Status::OK;
@ -545,8 +503,7 @@ Status GRPCService::LoginAbort(ServerContext *, LoginAbortRequest const *request
//****************************************************************************************************************************************************
/// \return The status for the call.
//****************************************************************************************************************************************************
Status GRPCService::CheckUpdate(ServerContext *, Empty const *, Empty *)
{
Status GRPCService::CheckUpdate(ServerContext *, Empty const *, Empty *) {
/// \todo simulate update availability.
app().log().debug(__FUNCTION__);
app().log().info("Check for updates");
@ -557,8 +514,7 @@ Status GRPCService::CheckUpdate(ServerContext *, Empty const *, Empty *)
//****************************************************************************************************************************************************
/// \return The status for the call.
//****************************************************************************************************************************************************
Status GRPCService::InstallUpdate(ServerContext *, Empty const *, Empty *)
{
Status GRPCService::InstallUpdate(ServerContext *, Empty const *, Empty *) {
/// Simulate update availability.
app().log().debug(__FUNCTION__);
app().log().info("Install update");
@ -570,30 +526,29 @@ Status GRPCService::InstallUpdate(ServerContext *, Empty const *, Empty *)
/// \param[in] request The request.
/// \return The status for the call.
//****************************************************************************************************************************************************
Status GRPCService::SetIsAutomaticUpdateOn(ServerContext *, BoolValue const *request, Empty *)
{
Status GRPCService::SetIsAutomaticUpdateOn(ServerContext *, BoolValue const *request, Empty *) {
app().log().debug(__FUNCTION__);
qtProxy_.setIsAutomaticUpdateOn(request->value());
return Status::OK;
}
//****************************************************************************************************************************************************
/// \param[out] response The response.
/// \return The status for the call.
//****************************************************************************************************************************************************
Status GRPCService::IsAutomaticUpdateOn(ServerContext *, Empty const *, BoolValue *response)
{
Status GRPCService::IsAutomaticUpdateOn(ServerContext *, Empty const *, BoolValue *response) {
app().log().debug(__FUNCTION__);
response->set_value(app().mainWindow().settingsTab().isAutomaticUpdateOn());
return Status::OK;
}
//****************************************************************************************************************************************************
/// \param[in] response The response.
/// \return The status for the call
//****************************************************************************************************************************************************
Status GRPCService::DiskCachePath(ServerContext *, Empty const *, StringValue *response)
{
Status GRPCService::DiskCachePath(ServerContext *, Empty const *, StringValue *response) {
app().log().debug(__FUNCTION__);
response->set_value(app().mainWindow().settingsTab().diskCachePath().toStdString());
return Status::OK;
@ -604,18 +559,16 @@ Status GRPCService::DiskCachePath(ServerContext *, Empty const *, StringValue *r
/// \param[in] path The path.
/// \return The status for the call.
//****************************************************************************************************************************************************
Status GRPCService::SetDiskCachePath(ServerContext *, StringValue const *path, Empty *)
{
Status GRPCService::SetDiskCachePath(ServerContext *, StringValue const *path, Empty *) {
app().log().debug(__FUNCTION__);
SettingsTab &tab = app().mainWindow().settingsTab();
QString const qPath = QString::fromStdString(path->value());
// we mimic the behaviour of Bridge
if (!tab.nextCacheChangeWillSucceed())
if (!tab.nextCacheChangeWillSucceed()) {
qtProxy_.sendDelayedEvent(newDiskCacheErrorEvent(grpc::DiskCacheErrorType(tab.cacheError())));
else
{
} else {
qtProxy_.setDiskCachePath(qPath);
qtProxy_.sendDelayedEvent(newDiskCachePathChangedEvent(qPath));
}
@ -629,8 +582,7 @@ Status GRPCService::SetDiskCachePath(ServerContext *, StringValue const *path, E
/// \param[in] request The request.
/// \return The status for the call.
//****************************************************************************************************************************************************
Status GRPCService::SetIsDoHEnabled(ServerContext *, BoolValue const *request, Empty *)
{
Status GRPCService::SetIsDoHEnabled(ServerContext *, BoolValue const *request, Empty *) {
app().log().debug(__FUNCTION__);
qtProxy_.setIsDoHEnabled(request->value());
return Status::OK;
@ -641,8 +593,7 @@ Status GRPCService::SetIsDoHEnabled(ServerContext *, BoolValue const *request, E
/// \param[out] response The response
/// \return The status for the call.
//****************************************************************************************************************************************************
Status GRPCService::IsDoHEnabled(ServerContext *, Empty const *, BoolValue *response)
{
Status GRPCService::IsDoHEnabled(ServerContext *, Empty const *, BoolValue *response) {
app().log().debug(__FUNCTION__);
response->set_value(app().mainWindow().settingsTab().isDoHEnabled());
return Status::OK;
@ -653,8 +604,7 @@ Status GRPCService::IsDoHEnabled(ServerContext *, Empty const *, BoolValue *resp
/// \param[in] settings The IMAP/SMTP settings.
/// \return The status for the call.
//****************************************************************************************************************************************************
Status GRPCService::SetMailServerSettings(::grpc::ServerContext *context, ImapSmtpSettings const *settings, Empty *)
{
Status GRPCService::SetMailServerSettings(::grpc::ServerContext *context, ImapSmtpSettings const *settings, Empty *) {
app().log().debug(__FUNCTION__);
qtProxy_.setMailServerSettings(settings->imapport(), settings->smtpport(), settings->usesslforimap(), settings->usesslforsmtp());
qtProxy_.sendDelayedEvent(newMailServerSettingsChanged(*settings));
@ -667,10 +617,9 @@ Status GRPCService::SetMailServerSettings(::grpc::ServerContext *context, ImapSm
/// \param[out] outSettings The settings
/// \return The status for the call.
//****************************************************************************************************************************************************
Status GRPCService::MailServerSettings(::grpc::ServerContext *, Empty const *, ImapSmtpSettings *outSettings)
{
Status GRPCService::MailServerSettings(::grpc::ServerContext *, Empty const *, ImapSmtpSettings *outSettings) {
app().log().debug(__FUNCTION__);
SettingsTab& tab = app().mainWindow().settingsTab();
SettingsTab &tab = app().mainWindow().settingsTab();
outSettings->set_imapport(tab.imapPort());
outSettings->set_smtpport(tab.smtpPort());
outSettings->set_usesslforimap(tab.useSSLForIMAP());
@ -683,8 +632,7 @@ Status GRPCService::MailServerSettings(::grpc::ServerContext *, Empty const *, I
/// \param[out] response The response.
/// \return The status for the call.
//****************************************************************************************************************************************************
Status GRPCService::Hostname(ServerContext *, Empty const *, StringValue *response)
{
Status GRPCService::Hostname(ServerContext *, Empty const *, StringValue *response) {
app().log().debug(__FUNCTION__);
response->set_value(app().mainWindow().settingsTab().hostname().toStdString());
return Status::OK;
@ -696,8 +644,7 @@ Status GRPCService::Hostname(ServerContext *, Empty const *, StringValue *respon
/// \param[out] response The response.
/// \return The status for the call.
//****************************************************************************************************************************************************
Status GRPCService::IsPortFree(ServerContext *, Int32Value const *request, BoolValue *response)
{
Status GRPCService::IsPortFree(ServerContext *, Int32Value const *request, BoolValue *response) {
app().log().debug(__FUNCTION__);
response->set_value(app().mainWindow().settingsTab().isPortFree());
return Status::OK;
@ -708,8 +655,7 @@ Status GRPCService::IsPortFree(ServerContext *, Int32Value const *request, BoolV
/// \param[out] response The response.
/// \return The status for the call
//****************************************************************************************************************************************************
Status GRPCService::AvailableKeychains(ServerContext *, Empty const *, AvailableKeychainsResponse *response)
{
Status GRPCService::AvailableKeychains(ServerContext *, Empty const *, AvailableKeychainsResponse *response) {
/// \todo Implement keychains configuration.
app().log().debug(__FUNCTION__);
response->clear_keychains();
@ -722,8 +668,7 @@ Status GRPCService::AvailableKeychains(ServerContext *, Empty const *, Available
/// \param[in] request The request.
/// \return The status for the call
//****************************************************************************************************************************************************
Status GRPCService::SetCurrentKeychain(ServerContext *, StringValue const *request, Empty *)
{
Status GRPCService::SetCurrentKeychain(ServerContext *, StringValue const *request, Empty *) {
/// \todo Implement keychains configuration.
app().log().debug(__FUNCTION__);
return Status::OK;
@ -734,8 +679,7 @@ Status GRPCService::SetCurrentKeychain(ServerContext *, StringValue const *reque
/// \param[out] response The response.
/// \return The status for the call
//****************************************************************************************************************************************************
Status GRPCService::CurrentKeychain(ServerContext *, Empty const *, StringValue *response)
{
Status GRPCService::CurrentKeychain(ServerContext *, Empty const *, StringValue *response) {
/// \todo Implement keychains configuration.
app().log().debug(__FUNCTION__);
response->set_value(defaultKeychain.toStdString());
@ -747,17 +691,16 @@ Status GRPCService::CurrentKeychain(ServerContext *, Empty const *, StringValue
/// \param[out] response The response.
/// \return The status for the call
//****************************************************************************************************************************************************
Status GRPCService::GetUserList(ServerContext *, Empty const *, UserListResponse *response)
{
Status GRPCService::GetUserList(ServerContext *, Empty const *, UserListResponse *response) {
app().log().debug(__FUNCTION__);
response->clear_users();
QList<SPUser> userList = app().mainWindow().usersTab().userTable().users();
RepeatedPtrField<grpc::User> *users = response->mutable_users();
for (SPUser const &user: userList)
{
if (!user)
for (SPUser const &user: userList) {
if (!user) {
continue;
}
users->Add();
grpc::User &grpcUser = (*users)[users->size() - 1];
userToGRPC(*user, grpcUser);
@ -772,13 +715,13 @@ Status GRPCService::GetUserList(ServerContext *, Empty const *, UserListResponse
/// \param[out] response The response.
/// \return The status for the call.
//****************************************************************************************************************************************************
Status GRPCService::GetUser(ServerContext *, StringValue const *request, grpc::User *response)
{
Status GRPCService::GetUser(ServerContext *, StringValue const *request, grpc::User *response) {
app().log().debug(__FUNCTION__);
QString userID = QString::fromStdString(request->value());
SPUser user = app().mainWindow().usersTab().userWithID(userID);
if (!user)
if (!user) {
return Status(NOT_FOUND, QString("user not found %1").arg(userID).toStdString());
}
userToGRPC(*user, *response);
return Status::OK;
@ -789,8 +732,7 @@ Status GRPCService::GetUser(ServerContext *, StringValue const *request, grpc::U
/// \param[in] request The request.
/// \return The status for the call.
//****************************************************************************************************************************************************
Status GRPCService::SetUserSplitMode(ServerContext *, UserSplitModeRequest const *request, Empty *)
{
Status GRPCService::SetUserSplitMode(ServerContext *, UserSplitModeRequest const *request, Empty *) {
app().log().debug(__FUNCTION__);
qtProxy_.setUserSplitMode(QString::fromStdString(request->userid()), request->active());
return Status::OK;
@ -801,8 +743,7 @@ Status GRPCService::SetUserSplitMode(ServerContext *, UserSplitModeRequest const
/// \param[in] request The request.
/// \return The status for the call.
//****************************************************************************************************************************************************
Status GRPCService::LogoutUser(ServerContext *, StringValue const *request, Empty *)
{
Status GRPCService::LogoutUser(ServerContext *, StringValue const *request, Empty *) {
app().log().debug(__FUNCTION__);
qtProxy_.logoutUser(QString::fromStdString(request->value()));
return Status::OK;
@ -813,8 +754,7 @@ Status GRPCService::LogoutUser(ServerContext *, StringValue const *request, Empt
/// \param[in] request The request.
/// \return The status for the call.
//****************************************************************************************************************************************************
Status GRPCService::RemoveUser(ServerContext *, StringValue const *request, Empty *)
{
Status GRPCService::RemoveUser(ServerContext *, StringValue const *request, Empty *) {
app().log().debug(__FUNCTION__);
qtProxy_.removeUser(QString::fromStdString(request->value()));
return Status::OK;
@ -824,8 +764,7 @@ Status GRPCService::RemoveUser(ServerContext *, StringValue const *request, Empt
//****************************************************************************************************************************************************
/// \param[in] request The request.
//****************************************************************************************************************************************************
Status GRPCService::ConfigureUserAppleMail(ServerContext *, ConfigureAppleMailRequest const *request, Empty *)
{
Status GRPCService::ConfigureUserAppleMail(ServerContext *, ConfigureAppleMailRequest const *request, Empty *) {
app().log().debug(__FUNCTION__);
qtProxy_.configureUserAppleMail(QString::fromStdString(request->userid()), QString::fromStdString(request->address()));
return Status::OK;
@ -837,24 +776,22 @@ Status GRPCService::ConfigureUserAppleMail(ServerContext *, ConfigureAppleMailRe
/// \param[in] writer The writer
/// \return The status for the call.
//****************************************************************************************************************************************************
Status GRPCService::RunEventStream(ServerContext *, EventStreamRequest const *request, ServerWriter<StreamEvent> *writer)
{
Status GRPCService::RunEventStream(ServerContext *, EventStreamRequest const *request, ServerWriter<StreamEvent> *writer) {
app().log().debug(__FUNCTION__);
{
QMutexLocker locker(&eventStreamMutex_);
if (isStreaming_)
if (isStreaming_) {
return { grpc::ALREADY_EXISTS, "the service is already streaming" };
}
isStreaming_ = true;
qtProxy_.setIsStreaming(true);
qtProxy_.setClientPlatform(QString::fromStdString(request->clientplatform()));
eventStreamShouldStop_ = false;
}
while (true)
{
while (true) {
QMutexLocker locker(&eventStreamMutex_);
if (eventStreamShouldStop_)
{
if (eventStreamShouldStop_) {
qtProxy_.setIsStreaming(false);
qtProxy_.setClientPlatform(QString());
isStreaming_ = false;
@ -862,8 +799,7 @@ Status GRPCService::RunEventStream(ServerContext *, EventStreamRequest const *re
}
if (eventQueue_.isEmpty())
{
if (eventQueue_.isEmpty()) {
locker.unlock();
QThread::msleep(100);
continue;
@ -872,10 +808,11 @@ Status GRPCService::RunEventStream(ServerContext *, EventStreamRequest const *re
eventQueue_.pop_front();
locker.unlock();
if (writer->Write(*event))
if (writer->Write(*event)) {
app().log().debug(QString("event sent: %1").arg(QString::fromStdString(event->ShortDebugString())));
else
} else {
app().log().error(QString("Could not send event: %1").arg(QString::fromStdString(event->ShortDebugString())));
}
}
}
@ -883,12 +820,12 @@ Status GRPCService::RunEventStream(ServerContext *, EventStreamRequest const *re
//****************************************************************************************************************************************************
/// \return The status for the call.
//****************************************************************************************************************************************************
Status GRPCService::StopEventStream(ServerContext *, Empty const *, Empty *)
{
Status GRPCService::StopEventStream(ServerContext *, Empty const *, Empty *) {
app().log().debug(__FUNCTION__);
QMutexLocker mutex(&eventStreamMutex_);
if (!isStreaming_)
if (!isStreaming_) {
return Status(NOT_FOUND, "The service is not streaming");
}
eventStreamShouldStop_ = true;
return Status::OK;
}
@ -898,10 +835,10 @@ Status GRPCService::StopEventStream(ServerContext *, Empty const *, Empty *)
/// \param[in] event The event
/// \return true if the event was queued, and false if the server in not streaming.
//****************************************************************************************************************************************************
bool GRPCService::sendEvent(SPStreamEvent const &event)
{
bool GRPCService::sendEvent(SPStreamEvent const &event) {
QMutexLocker mutexLocker(&eventStreamMutex_);
if (isStreaming_)
if (isStreaming_) {
eventQueue_.push_back(event);
}
return isStreaming_;
}

View File

@ -28,8 +28,7 @@
//**********************************************************************************************************************
/// \brief gRPC server implementation.
//**********************************************************************************************************************
class GRPCService : public grpc::Bridge::Service
{
class GRPCService : public grpc::Bridge::Service {
public: // member functions.
GRPCService() = default; ///< Default constructor.
@ -42,29 +41,29 @@ public: // member functions.
bool isStreaming() const; ///< Check if the service is currently streaming events.
grpc::Status CheckTokens(::grpc::ServerContext *context, ::google::protobuf::StringValue const *request, ::google::protobuf::StringValue *response) override;
grpc::Status AddLogEntry(::grpc::ServerContext *, ::grpc::AddLogEntryRequest const *request, ::google::protobuf::Empty *) override;
grpc::Status GuiReady(::grpc::ServerContext *, ::google::protobuf::Empty const*, ::google::protobuf::Empty *) override;
grpc::Status Quit(::grpc::ServerContext *, ::google::protobuf::Empty const*, ::google::protobuf::Empty *) override;
grpc::Status Restart(::grpc::ServerContext *, ::google::protobuf::Empty const*, ::google::protobuf::Empty *) override;
grpc::Status ShowOnStartup(::grpc::ServerContext *, ::google::protobuf::Empty const*, ::google::protobuf::BoolValue *response) override;
grpc::Status ShowSplashScreen(::grpc::ServerContext *, ::google::protobuf::Empty const*, ::google::protobuf::BoolValue *response) override;
grpc::Status IsFirstGuiStart(::grpc::ServerContext *, ::google::protobuf::Empty const*, ::google::protobuf::BoolValue *response) override;
grpc::Status GuiReady(::grpc::ServerContext *, ::google::protobuf::Empty const *, ::google::protobuf::Empty *) override;
grpc::Status Quit(::grpc::ServerContext *, ::google::protobuf::Empty const *, ::google::protobuf::Empty *) override;
grpc::Status Restart(::grpc::ServerContext *, ::google::protobuf::Empty const *, ::google::protobuf::Empty *) override;
grpc::Status ShowOnStartup(::grpc::ServerContext *, ::google::protobuf::Empty const *, ::google::protobuf::BoolValue *response) override;
grpc::Status ShowSplashScreen(::grpc::ServerContext *, ::google::protobuf::Empty const *, ::google::protobuf::BoolValue *response) override;
grpc::Status IsFirstGuiStart(::grpc::ServerContext *, ::google::protobuf::Empty const *, ::google::protobuf::BoolValue *response) override;
grpc::Status SetIsAutostartOn(::grpc::ServerContext *, ::google::protobuf::BoolValue const *request, ::google::protobuf::Empty *) override;
grpc::Status IsAutostartOn(::grpc::ServerContext *, ::google::protobuf::Empty const*, ::google::protobuf::BoolValue *response) override;
grpc::Status IsAutostartOn(::grpc::ServerContext *, ::google::protobuf::Empty const *, ::google::protobuf::BoolValue *response) override;
grpc::Status SetIsBetaEnabled(::grpc::ServerContext *, ::google::protobuf::BoolValue const *request, ::google::protobuf::Empty *) override;
grpc::Status IsBetaEnabled(::grpc::ServerContext *, ::google::protobuf::Empty const*, ::google::protobuf::BoolValue *response) override;
grpc::Status IsBetaEnabled(::grpc::ServerContext *, ::google::protobuf::Empty const *, ::google::protobuf::BoolValue *response) override;
grpc::Status SetIsAllMailVisible(::grpc::ServerContext *context, ::google::protobuf::BoolValue const *request, ::google::protobuf::Empty *response) override;
grpc::Status IsAllMailVisible(::grpc::ServerContext *context, ::google::protobuf::Empty const *request, ::google::protobuf::BoolValue *response) override;
grpc::Status GoOs(::grpc::ServerContext *, ::google::protobuf::Empty const*, ::google::protobuf::StringValue *response) override;
grpc::Status TriggerReset(::grpc::ServerContext *, ::google::protobuf::Empty const*, ::google::protobuf::Empty *) override;
grpc::Status Version(::grpc::ServerContext *, ::google::protobuf::Empty const*, ::google::protobuf::StringValue *response) override;
grpc::Status LogsPath(::grpc::ServerContext *, ::google::protobuf::Empty const*, ::google::protobuf::StringValue *response) override;
grpc::Status LicensePath(::grpc::ServerContext *, ::google::protobuf::Empty const*, ::google::protobuf::StringValue *response) override;
grpc::Status ReleaseNotesPageLink(::grpc::ServerContext *, ::google::protobuf::Empty const*, ::google::protobuf::StringValue *response) override;
grpc::Status DependencyLicensesLink(::grpc::ServerContext *, ::google::protobuf::Empty const*, ::google::protobuf::StringValue *response) override;
grpc::Status LandingPageLink(::grpc::ServerContext *, ::google::protobuf::Empty const*, ::google::protobuf::StringValue *response) override;
grpc::Status GoOs(::grpc::ServerContext *, ::google::protobuf::Empty const *, ::google::protobuf::StringValue *response) override;
grpc::Status TriggerReset(::grpc::ServerContext *, ::google::protobuf::Empty const *, ::google::protobuf::Empty *) override;
grpc::Status Version(::grpc::ServerContext *, ::google::protobuf::Empty const *, ::google::protobuf::StringValue *response) override;
grpc::Status LogsPath(::grpc::ServerContext *, ::google::protobuf::Empty const *, ::google::protobuf::StringValue *response) override;
grpc::Status LicensePath(::grpc::ServerContext *, ::google::protobuf::Empty const *, ::google::protobuf::StringValue *response) override;
grpc::Status ReleaseNotesPageLink(::grpc::ServerContext *, ::google::protobuf::Empty const *, ::google::protobuf::StringValue *response) override;
grpc::Status DependencyLicensesLink(::grpc::ServerContext *, ::google::protobuf::Empty const *, ::google::protobuf::StringValue *response) override;
grpc::Status LandingPageLink(::grpc::ServerContext *, ::google::protobuf::Empty const *, ::google::protobuf::StringValue *response) override;
grpc::Status SetColorSchemeName(::grpc::ServerContext *, ::google::protobuf::StringValue const *request, ::google::protobuf::Empty *) override;
grpc::Status ColorSchemeName(::grpc::ServerContext *, ::google::protobuf::Empty const*, ::google::protobuf::StringValue *response) override;
grpc::Status CurrentEmailClient(::grpc::ServerContext *, ::google::protobuf::Empty const*, ::google::protobuf::StringValue *response) override;
grpc::Status ColorSchemeName(::grpc::ServerContext *, ::google::protobuf::Empty const *, ::google::protobuf::StringValue *response) override;
grpc::Status CurrentEmailClient(::grpc::ServerContext *, ::google::protobuf::Empty const *, ::google::protobuf::StringValue *response) override;
grpc::Status ReportBug(::grpc::ServerContext *, ::grpc::ReportBugRequest const *request, ::google::protobuf::Empty *) override;
grpc::Status ExportTLSCertificates(::grpc::ServerContext *context, ::google::protobuf::StringValue const *request, ::google::protobuf::Empty *response) override;
grpc::Status ForceLauncher(::grpc::ServerContext *, ::google::protobuf::StringValue const *request, ::google::protobuf::Empty *) override;
@ -73,29 +72,29 @@ public: // member functions.
grpc::Status Login2FA(::grpc::ServerContext *, ::grpc::LoginRequest const *request, ::google::protobuf::Empty *) override;
grpc::Status Login2Passwords(::grpc::ServerContext *, ::grpc::LoginRequest const *request, ::google::protobuf::Empty *) override;
grpc::Status LoginAbort(::grpc::ServerContext *, ::grpc::LoginAbortRequest const *request, ::google::protobuf::Empty *) override;
grpc::Status CheckUpdate(::grpc::ServerContext *, ::google::protobuf::Empty const*, ::google::protobuf::Empty *) override;
grpc::Status InstallUpdate(::grpc::ServerContext *, ::google::protobuf::Empty const*, ::google::protobuf::Empty *) override;
grpc::Status CheckUpdate(::grpc::ServerContext *, ::google::protobuf::Empty const *, ::google::protobuf::Empty *) override;
grpc::Status InstallUpdate(::grpc::ServerContext *, ::google::protobuf::Empty const *, ::google::protobuf::Empty *) override;
grpc::Status SetIsAutomaticUpdateOn(::grpc::ServerContext *, ::google::protobuf::BoolValue const *request, ::google::protobuf::Empty *) override;
grpc::Status IsAutomaticUpdateOn(::grpc::ServerContext *, ::google::protobuf::Empty const*, ::google::protobuf::BoolValue *response) override;
grpc::Status DiskCachePath(::grpc::ServerContext *, ::google::protobuf::Empty const*, ::google::protobuf::StringValue *response) override;
grpc::Status SetDiskCachePath(::grpc::ServerContext *, ::google::protobuf::StringValue const*, ::google::protobuf::Empty *r) override;
grpc::Status IsAutomaticUpdateOn(::grpc::ServerContext *, ::google::protobuf::Empty const *, ::google::protobuf::BoolValue *response) override;
grpc::Status DiskCachePath(::grpc::ServerContext *, ::google::protobuf::Empty const *, ::google::protobuf::StringValue *response) override;
grpc::Status SetDiskCachePath(::grpc::ServerContext *, ::google::protobuf::StringValue const *, ::google::protobuf::Empty *r) override;
grpc::Status SetIsDoHEnabled(::grpc::ServerContext *, ::google::protobuf::BoolValue const *request, ::google::protobuf::Empty *) override;
grpc::Status IsDoHEnabled(::grpc::ServerContext *, ::google::protobuf::Empty const*, ::google::protobuf::BoolValue *response) override;
grpc::Status IsDoHEnabled(::grpc::ServerContext *, ::google::protobuf::Empty const *, ::google::protobuf::BoolValue *response) override;
grpc::Status SetMailServerSettings(::grpc::ServerContext *context, ::grpc::ImapSmtpSettings const *request, ::google::protobuf::Empty *response) override;
grpc::Status MailServerSettings(::grpc::ServerContext *context, ::google::protobuf::Empty const *request, ::grpc::ImapSmtpSettings *response) override;
grpc::Status Hostname(::grpc::ServerContext *, ::google::protobuf::Empty const*, ::google::protobuf::StringValue *response) override;
grpc::Status Hostname(::grpc::ServerContext *, ::google::protobuf::Empty const *, ::google::protobuf::StringValue *response) override;
grpc::Status IsPortFree(::grpc::ServerContext *, ::google::protobuf::Int32Value const *request, ::google::protobuf::BoolValue *response) override;
grpc::Status AvailableKeychains(::grpc::ServerContext *, ::google::protobuf::Empty const*, ::grpc::AvailableKeychainsResponse *response) override;
grpc::Status AvailableKeychains(::grpc::ServerContext *, ::google::protobuf::Empty const *, ::grpc::AvailableKeychainsResponse *response) override;
grpc::Status SetCurrentKeychain(::grpc::ServerContext *, ::google::protobuf::StringValue const *request, ::google::protobuf::Empty *) override;
grpc::Status CurrentKeychain(::grpc::ServerContext *, ::google::protobuf::Empty const*, ::google::protobuf::StringValue *response) override;
grpc::Status GetUserList(::grpc::ServerContext *, ::google::protobuf::Empty const*, ::grpc::UserListResponse *response) override;
grpc::Status CurrentKeychain(::grpc::ServerContext *, ::google::protobuf::Empty const *, ::google::protobuf::StringValue *response) override;
grpc::Status GetUserList(::grpc::ServerContext *, ::google::protobuf::Empty const *, ::grpc::UserListResponse *response) override;
grpc::Status GetUser(::grpc::ServerContext *, ::google::protobuf::StringValue const *request, ::grpc::User *response) override;
grpc::Status SetUserSplitMode(::grpc::ServerContext *, ::grpc::UserSplitModeRequest const *request, ::google::protobuf::Empty *) override;
grpc::Status LogoutUser(::grpc::ServerContext *, ::google::protobuf::StringValue const *request, ::google::protobuf::Empty *) override;
grpc::Status RemoveUser(::grpc::ServerContext *, ::google::protobuf::StringValue const *request, ::google::protobuf::Empty *) override;
grpc::Status ConfigureUserAppleMail(::grpc::ServerContext *, ::grpc::ConfigureAppleMailRequest const *request, ::google::protobuf::Empty *) override;
grpc::Status RunEventStream(::grpc::ServerContext *, ::grpc::EventStreamRequest const *request, ::grpc::ServerWriter<::grpc::StreamEvent> *writer) override;
grpc::Status StopEventStream(::grpc::ServerContext *, ::google::protobuf::Empty const*, ::google::protobuf::Empty *) override;
grpc::Status StopEventStream(::grpc::ServerContext *, ::google::protobuf::Empty const *, ::google::protobuf::Empty *) override;
bool sendEvent(bridgepp::SPStreamEvent const &event); ///< Queue an event for sending through the event stream.

View File

@ -23,8 +23,7 @@
using namespace bridgepp;
namespace
{
namespace {
//****************************************************************************************************************************************************
@ -32,12 +31,12 @@ namespace
/// \param[in] message The log message.
/// \param[in] logEdit The plain text edit widget that displays the log.
//****************************************************************************************************************************************************
void addEntryToLogEdit(bridgepp::Log::Level level, const QString &message, QPlainTextEdit &logEdit)
{
void addEntryToLogEdit(bridgepp::Log::Level level, const QString &message, QPlainTextEdit &logEdit) {
/// \todo This may cause performance issue when log grows big. A better alternative should be implemented.
QString log = logEdit.toPlainText().trimmed();
if (!log.isEmpty())
if (!log.isEmpty()) {
log += "\n";
}
logEdit.setPlainText(log + Log::logEntryToString(level, QDateTime::currentDateTime(), message));
}
@ -49,14 +48,13 @@ void addEntryToLogEdit(bridgepp::Log::Level level, const QString &message, QPlai
/// \param[in] parent The parent widget of the window.
//****************************************************************************************************************************************************
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
: QMainWindow(parent) {
ui_.setupUi(this);
ui_.tabTop->setCurrentIndex(0);
ui_.tabBottom->setCurrentIndex(0);
ui_.splitter->setStretchFactor(0, 0);
ui_.splitter->setStretchFactor(1, 1);
ui_.splitter->setSizes({100, 10000});
ui_.splitter->setSizes({ 100, 10000 });
connect(&app().log(), &Log::entryAdded, this, &MainWindow::addLogEntry);
connect(&app().bridgeGUILog(), &Log::entryAdded, this, &MainWindow::addBridgeGUILogEntry);
}
@ -65,8 +63,7 @@ MainWindow::MainWindow(QWidget *parent)
//****************************************************************************************************************************************************
/// \return A reference to the 'General' tab.
//****************************************************************************************************************************************************
SettingsTab &MainWindow::settingsTab()
{
SettingsTab &MainWindow::settingsTab() {
return *ui_.settingsTab;
}
@ -74,8 +71,7 @@ SettingsTab &MainWindow::settingsTab()
//****************************************************************************************************************************************************
/// \return A reference to the users tab.
//****************************************************************************************************************************************************
UsersTab &MainWindow::usersTab()
{
UsersTab &MainWindow::usersTab() {
return *ui_.usersTab;
}
@ -84,8 +80,7 @@ UsersTab &MainWindow::usersTab()
/// \param[in] level The log level.
/// \param[in] message The log message
//****************************************************************************************************************************************************
void MainWindow::addLogEntry(bridgepp::Log::Level level, const QString &message)
{
void MainWindow::addLogEntry(bridgepp::Log::Level level, const QString &message) {
addEntryToLogEdit(level, message, *ui_.editLog);
}
@ -94,8 +89,7 @@ void MainWindow::addLogEntry(bridgepp::Log::Level level, const QString &message)
/// \param[in] level The log level.
/// \param[in] message The log message
//****************************************************************************************************************************************************
void MainWindow::addBridgeGUILogEntry(bridgepp::Log::Level level, const QString &message)
{
void MainWindow::addBridgeGUILogEntry(bridgepp::Log::Level level, const QString &message) {
addEntryToLogEdit(level, message, *ui_.editBridgeGUILog);
}
@ -103,8 +97,7 @@ void MainWindow::addBridgeGUILogEntry(bridgepp::Log::Level level, const QString
//****************************************************************************************************************************************************
/// \param[in] event The event.
//****************************************************************************************************************************************************
void MainWindow::sendDelayedEvent(SPStreamEvent const &event)
{
void MainWindow::sendDelayedEvent(SPStreamEvent const &event) {
QTimer::singleShot(this->settingsTab().eventDelayMs(), [event] { app().grpc().sendEvent(event); });
}

View File

@ -28,8 +28,7 @@
//**********************************************************************************************************************
/// \brief Main window class
//**********************************************************************************************************************
class MainWindow : public QMainWindow
{
class MainWindow : public QMainWindow {
Q_OBJECT
public: // member functions.
explicit MainWindow(QWidget *parent); ///< Default constructor.
@ -43,7 +42,7 @@ public: // member functions.
UsersTab &usersTab(); ///< Returns a reference to the 'Users' 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.
void sendDelayedEvent(bridgepp::SPStreamEvent const &event); ///< Sends a gRPC event after the delay specified in the UI. The call is non blocking.
private slots:
void addLogEntry(bridgepp::Log::Level level, QString const &message); ///< Add an entry to the log.

View File

@ -25,8 +25,7 @@
using namespace bridgepp;
namespace
{
namespace {
QString const colorSchemeDark = "dark"; ///< The dark color scheme name.
QString const colorSchemeLight = "light"; ///< THe light color scheme name.
}
@ -36,44 +35,47 @@ QString const colorSchemeLight = "light"; ///< THe light color scheme name.
/// \param[in] parent The parent widget of the tab.
//****************************************************************************************************************************************************
SettingsTab::SettingsTab(QWidget *parent)
: 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_.buttonAPICertIssue, &QPushButton::clicked, []() {app().grpc().sendEvent(newApiCertIssueEvent()); });
connect(ui_.buttonDiskCacheUnavailable, &QPushButton::clicked,[]() {app().grpc().sendEvent(
newDiskCacheErrorEvent(grpc::DiskCacheErrorType::DISK_CACHE_UNAVAILABLE_ERROR)); });
connect(ui_.buttonDiskFull, &QPushButton::clicked,[]() {app().grpc().sendEvent(
newDiskCacheErrorEvent(grpc::DiskCacheErrorType::DISK_FULL_ERROR)); });
connect(ui_.buttonNoActiveKeyForRecipient, &QPushButton::clicked, [&]() {app().grpc().sendEvent(
newNoActiveKeyForRecipientEvent(ui_.editNoActiveKeyForRecipient->text())); });
connect(ui_.buttonAPICertIssue, &QPushButton::clicked, []() { app().grpc().sendEvent(newApiCertIssueEvent()); });
connect(ui_.buttonDiskCacheUnavailable, &QPushButton::clicked, []() {
app().grpc().sendEvent(
newDiskCacheErrorEvent(grpc::DiskCacheErrorType::DISK_CACHE_UNAVAILABLE_ERROR));
});
connect(ui_.buttonDiskFull, &QPushButton::clicked, []() {
app().grpc().sendEvent(
newDiskCacheErrorEvent(grpc::DiskCacheErrorType::DISK_FULL_ERROR));
});
connect(ui_.buttonNoActiveKeyForRecipient, &QPushButton::clicked, [&]() {
app().grpc().sendEvent(
newNoActiveKeyForRecipientEvent(ui_.editNoActiveKeyForRecipient->text()));
});
connect(ui_.checkNextCacheChangeWillSucceed, &QCheckBox::toggled, this, &SettingsTab::updateGUIState);
this->resetUI();
this->updateGUIState();
}
//****************************************************************************************************************************************************
//
//****************************************************************************************************************************************************
void SettingsTab::updateGUIState()
{
void SettingsTab::updateGUIState() {
bool connected = app().grpc().isStreaming();
for (QWidget *widget: { ui_.groupVersion, ui_.groupGeneral, ui_.groupMail, ui_.groupPaths, ui_.groupCache })
for (QWidget *widget: { ui_.groupVersion, ui_.groupGeneral, ui_.groupMail, ui_.groupPaths, ui_.groupCache }) {
widget->setEnabled(!connected);
ui_.comboCacheError -> setEnabled(!ui_.checkNextCacheChangeWillSucceed->isChecked());
}
ui_.comboCacheError->setEnabled(!ui_.checkNextCacheChangeWillSucceed->isChecked());
}
//****************************************************************************************************************************************************
/// \param[in] isStreaming Is the event stream on?
//****************************************************************************************************************************************************
void SettingsTab::setIsStreaming(bool isStreaming)
{
void SettingsTab::setIsStreaming(bool isStreaming) {
ui_.labelStreamingValue->setText(isStreaming ? "Yes" : "No");
this->updateGUIState();
}
@ -82,8 +84,7 @@ void SettingsTab::setIsStreaming(bool isStreaming)
//****************************************************************************************************************************************************
/// \param[in] clientPlatform The client platform.
//****************************************************************************************************************************************************
void SettingsTab::setClientPlatform(QString const &clientPlatform)
{
void SettingsTab::setClientPlatform(QString const &clientPlatform) {
ui_.labelClientPlatformValue->setText(clientPlatform);
}
@ -91,8 +92,7 @@ void SettingsTab::setClientPlatform(QString const &clientPlatform)
//****************************************************************************************************************************************************
/// \return The version of Bridge
//****************************************************************************************************************************************************
QString SettingsTab::bridgeVersion() const
{
QString SettingsTab::bridgeVersion() const {
return ui_.editVersion->text();
}
@ -100,8 +100,7 @@ QString SettingsTab::bridgeVersion() const
//****************************************************************************************************************************************************
/// \return The OS as a Go GOOS compatible value ("darwin", "linux" or "windows").
//****************************************************************************************************************************************************
QString SettingsTab::os() const
{
QString SettingsTab::os() const {
return ui_.comboOS->currentText();
}
@ -109,8 +108,7 @@ QString SettingsTab::os() const
//****************************************************************************************************************************************************
/// \return The value for the 'Current Email Client' edit.
//****************************************************************************************************************************************************
QString SettingsTab::currentEmailClient() const
{
QString SettingsTab::currentEmailClient() const {
return ui_.editCurrentEmailClient->text();
}
@ -118,8 +116,7 @@ QString SettingsTab::currentEmailClient() const
//****************************************************************************************************************************************************
/// \param[in] ready Is the GUI ready?
//****************************************************************************************************************************************************
void SettingsTab::setGUIReady(bool ready)
{
void SettingsTab::setGUIReady(bool ready) {
this->updateGUIState();
ui_.labelGUIReadyValue->setText(ready ? "Yes" : "No");
}
@ -128,8 +125,7 @@ void SettingsTab::setGUIReady(bool ready)
//****************************************************************************************************************************************************
/// \return true iff the 'Show On Startup' check box is checked.
//****************************************************************************************************************************************************
bool SettingsTab::showOnStartup() const
{
bool SettingsTab::showOnStartup() const {
return ui_.checkShowOnStartup->isChecked();
}
@ -137,8 +133,7 @@ bool SettingsTab::showOnStartup() const
//****************************************************************************************************************************************************
/// \return true iff the 'Show Splash Screen' check box is checked.
//****************************************************************************************************************************************************
bool SettingsTab::showSplashScreen() const
{
bool SettingsTab::showSplashScreen() const {
return ui_.checkShowSplashScreen->isChecked();
}
@ -146,8 +141,7 @@ bool SettingsTab::showSplashScreen() const
//****************************************************************************************************************************************************
/// \return true iff the 'Show Splash Screen' check box is checked.
//****************************************************************************************************************************************************
bool SettingsTab::isFirstGUIStart() const
{
bool SettingsTab::isFirstGUIStart() const {
return ui_.checkIsFirstGUIStart->isChecked();
}
@ -155,8 +149,7 @@ bool SettingsTab::isFirstGUIStart() const
//****************************************************************************************************************************************************
/// \return true iff autosart is on.
//****************************************************************************************************************************************************
bool SettingsTab::isAutostartOn() const
{
bool SettingsTab::isAutostartOn() const {
return ui_.checkAutostart->isChecked();
}
@ -164,8 +157,7 @@ bool SettingsTab::isAutostartOn() const
//****************************************************************************************************************************************************
/// \param[in] on Should autostart be turned on?
//****************************************************************************************************************************************************
void SettingsTab::setIsAutostartOn(bool on)
{
void SettingsTab::setIsAutostartOn(bool on) {
ui_.checkAutostart->setChecked(on);
}
@ -173,8 +165,7 @@ void SettingsTab::setIsAutostartOn(bool on)
//****************************************************************************************************************************************************
/// \return true if the 'Use Dark Theme' check box is checked.
//****************************************************************************************************************************************************
QString SettingsTab::colorSchemeName() const
{
QString SettingsTab::colorSchemeName() const {
return ui_.checkDarkTheme->isChecked() ? colorSchemeDark : colorSchemeLight;
}
@ -182,8 +173,7 @@ QString SettingsTab::colorSchemeName() const
//****************************************************************************************************************************************************
/// \param[in] name True if the 'Use Dark Theme' check box should be checked.
//****************************************************************************************************************************************************
void SettingsTab::setColorSchemeName(QString const &name)
{
void SettingsTab::setColorSchemeName(QString const &name) {
ui_.checkDarkTheme->setChecked(name == colorSchemeDark);
}
@ -191,8 +181,7 @@ void SettingsTab::setColorSchemeName(QString const &name)
//****************************************************************************************************************************************************
/// \return true if the 'Beta Enabled' check box is checked.
//****************************************************************************************************************************************************
bool SettingsTab::isBetaEnabled() const
{
bool SettingsTab::isBetaEnabled() const {
return ui_.checkBetaEnabled->isChecked();
}
@ -200,8 +189,7 @@ bool SettingsTab::isBetaEnabled() const
//****************************************************************************************************************************************************
/// \param[in] enabled The new state for the 'Beta Enabled' check box.
//****************************************************************************************************************************************************
void SettingsTab::setIsBetaEnabled(bool enabled)
{
void SettingsTab::setIsBetaEnabled(bool enabled) {
ui_.checkBetaEnabled->setChecked(enabled);
}
@ -209,8 +197,7 @@ void SettingsTab::setIsBetaEnabled(bool enabled)
//****************************************************************************************************************************************************
/// \return true if the 'All Mail Visible' check box is checked.
//****************************************************************************************************************************************************
bool SettingsTab::isAllMailVisible() const
{
bool SettingsTab::isAllMailVisible() const {
return ui_.checkAllMailVisible->isChecked();
}
@ -218,8 +205,7 @@ bool SettingsTab::isAllMailVisible() const
//****************************************************************************************************************************************************
/// \param[in] visible The new value for the 'All Mail Visible' check box.
//****************************************************************************************************************************************************
void SettingsTab::setIsAllMailVisible(bool visible)
{
void SettingsTab::setIsAllMailVisible(bool visible) {
ui_.checkAllMailVisible->setChecked(visible);
}
@ -227,8 +213,7 @@ void SettingsTab::setIsAllMailVisible(bool visible)
//****************************************************************************************************************************************************
/// \return The delay to apply before sending automatically generated events.
//****************************************************************************************************************************************************
qint32 SettingsTab::eventDelayMs() const
{
qint32 SettingsTab::eventDelayMs() const {
return ui_.spinEventDelay->value();
}
@ -236,8 +221,7 @@ qint32 SettingsTab::eventDelayMs() const
//****************************************************************************************************************************************************
/// \return The path
//****************************************************************************************************************************************************
QString SettingsTab::logsPath() const
{
QString SettingsTab::logsPath() const {
return ui_.editLogsPath->text();
}
@ -245,8 +229,7 @@ QString SettingsTab::logsPath() const
//****************************************************************************************************************************************************
/// \return The path
//****************************************************************************************************************************************************
QString SettingsTab::licensePath() const
{
QString SettingsTab::licensePath() const {
return ui_.editLicensePath->text();
}
@ -254,8 +237,7 @@ QString SettingsTab::licensePath() const
//****************************************************************************************************************************************************
/// \return The link.
//****************************************************************************************************************************************************
QString SettingsTab::releaseNotesPageLink() const
{
QString SettingsTab::releaseNotesPageLink() const {
return ui_.editReleaseNotesLink->text();
}
@ -263,8 +245,7 @@ QString SettingsTab::releaseNotesPageLink() const
//****************************************************************************************************************************************************
/// \return The link.
//****************************************************************************************************************************************************
QString SettingsTab::dependencyLicenseLink() const
{
QString SettingsTab::dependencyLicenseLink() const {
return ui_.editDependencyLicenseLink->text();
}
@ -272,8 +253,7 @@ QString SettingsTab::dependencyLicenseLink() const
//****************************************************************************************************************************************************
/// \return The link.
//****************************************************************************************************************************************************
QString SettingsTab::landingPageLink() const
{
QString SettingsTab::landingPageLink() const {
return ui_.editLandingPageLink->text();
}
@ -287,8 +267,7 @@ QString SettingsTab::landingPageLink() const
/// \param[in] includeLogs Are the log included.
//****************************************************************************************************************************************************
void SettingsTab::setBugReport(QString const &osType, QString const &osVersion, QString const &emailClient, QString const &address,
QString const &description, bool includeLogs)
{
QString const &description, bool includeLogs) {
ui_.editOSType->setText(osType);
ui_.editOSVersion->setText(osVersion);
ui_.editEmailClient->setText(emailClient);
@ -301,8 +280,7 @@ void SettingsTab::setBugReport(QString const &osType, QString const &osVersion,
//****************************************************************************************************************************************************
/// \param[in] folderPath The folder path.
//****************************************************************************************************************************************************
void SettingsTab::exportTLSCertificates(QString const &folderPath)
{
void SettingsTab::exportTLSCertificates(QString const &folderPath) {
ui_.labeLastTLSCertsExport->setText(QString("%1 Export to %2")
.arg(QDateTime::currentDateTime().toString(Qt::ISODateWithMs))
.arg(folderPath));
@ -312,8 +290,7 @@ void SettingsTab::exportTLSCertificates(QString const &folderPath)
//****************************************************************************************************************************************************
/// \return The state of the check box.
//****************************************************************************************************************************************************
bool SettingsTab::nextBugReportWillSucceed() const
{
bool SettingsTab::nextBugReportWillSucceed() const {
return ui_.checkNextBugReportWillSucceed->isChecked();
}
@ -321,8 +298,7 @@ bool SettingsTab::nextBugReportWillSucceed() const
//****************************************************************************************************************************************************
/// \return true if the 'Next TLS key export will succeed' check box is checked
//****************************************************************************************************************************************************
bool SettingsTab::nextTLSCertExportWillSucceed() const
{
bool SettingsTab::nextTLSCertExportWillSucceed() const {
return ui_.checkTLSCertExportWillSucceed->isChecked();
}
@ -330,8 +306,7 @@ bool SettingsTab::nextTLSCertExportWillSucceed() const
//****************************************************************************************************************************************************
/// \return true if the 'Next TLS key export will succeed' check box is checked
//****************************************************************************************************************************************************
bool SettingsTab::nextTLSKeyExportWillSucceed() const
{
bool SettingsTab::nextTLSKeyExportWillSucceed() const {
return ui_.checkTLSKeyExportWillSucceed->isChecked();
}
@ -339,8 +314,7 @@ bool SettingsTab::nextTLSKeyExportWillSucceed() const
//****************************************************************************************************************************************************
/// \return The value of the 'Hostname' edit.
//****************************************************************************************************************************************************
QString SettingsTab::hostname() const
{
QString SettingsTab::hostname() const {
return ui_.editHostname->text();
}
@ -348,8 +322,7 @@ QString SettingsTab::hostname() const
//****************************************************************************************************************************************************
/// \return The value of the IMAP port spin box.
//****************************************************************************************************************************************************
qint32 SettingsTab::imapPort()
{
qint32 SettingsTab::imapPort() {
return ui_.spinPortIMAP->value();
}
@ -357,8 +330,7 @@ qint32 SettingsTab::imapPort()
//****************************************************************************************************************************************************
/// \return The value of the SMTP port spin box.
//****************************************************************************************************************************************************
qint32 SettingsTab::smtpPort()
{
qint32 SettingsTab::smtpPort() {
return ui_.spinPortSMTP->value();
}
@ -369,27 +341,26 @@ qint32 SettingsTab::smtpPort()
/// \param[in] useSSLForIMAP The IMAP connexion mode.
/// \param[in] useSSLForSMTP The IMAP connexion mode.
//****************************************************************************************************************************************************
void SettingsTab::setMailServerSettings(qint32 imapPort, qint32 smtpPort, bool useSSLForIMAP, bool useSSLForSMTP)
{
void SettingsTab::setMailServerSettings(qint32 imapPort, qint32 smtpPort, bool useSSLForIMAP, bool useSSLForSMTP) {
ui_.spinPortIMAP->setValue(imapPort);
ui_.spinPortSMTP->setValue(smtpPort);
ui_.checkUseSSLForIMAP->setChecked(useSSLForIMAP);
ui_.checkUseSSLForSMTP->setChecked(useSSLForSMTP);
}
//****************************************************************************************************************************************************
/// \return The state of the 'Use SSL for SMTP' check box.
//****************************************************************************************************************************************************
bool SettingsTab::useSSLForSMTP() const
{
return ui_.checkUseSSLForSMTP->isChecked();
}
//****************************************************************************************************************************************************
/// \return The state of the 'Use SSL for SMTP' check box.
//****************************************************************************************************************************************************
bool SettingsTab::useSSLForIMAP() const
{
bool SettingsTab::useSSLForSMTP() const {
return ui_.checkUseSSLForSMTP->isChecked();
}
//****************************************************************************************************************************************************
/// \return The state of the 'Use SSL for SMTP' check box.
//****************************************************************************************************************************************************
bool SettingsTab::useSSLForIMAP() const {
return ui_.checkUseSSLForIMAP->isChecked();
}
@ -397,8 +368,7 @@ bool SettingsTab::useSSLForIMAP() const
//****************************************************************************************************************************************************
/// \return The state of the the 'DoH enabled' check box.
//****************************************************************************************************************************************************
bool SettingsTab::isDoHEnabled() const
{
bool SettingsTab::isDoHEnabled() const {
return ui_.checkDoHEnabled->isChecked();
}
@ -406,8 +376,7 @@ bool SettingsTab::isDoHEnabled() const
//****************************************************************************************************************************************************
/// \param[in] enabled The state of the 'DoH enabled' check box.
//****************************************************************************************************************************************************
void SettingsTab::setIsDoHEnabled(bool enabled)
{
void SettingsTab::setIsDoHEnabled(bool enabled) {
ui_.checkDoHEnabled->setChecked(enabled);
}
@ -415,8 +384,7 @@ void SettingsTab::setIsDoHEnabled(bool enabled)
//****************************************************************************************************************************************************
/// \return The reply for the next IsPortFree gRPC call.
//****************************************************************************************************************************************************
bool SettingsTab::isPortFree() const
{
bool SettingsTab::isPortFree() const {
return ui_.checkIsPortFree->isChecked();
}
@ -424,8 +392,7 @@ bool SettingsTab::isPortFree() const
//****************************************************************************************************************************************************
/// \param[in] path The path of the local cache.
//****************************************************************************************************************************************************
void SettingsTab::setDiskCachePath(const QString &path)
{
void SettingsTab::setDiskCachePath(const QString &path) {
ui_.editDiskCachePath->setText(path);
}
@ -433,8 +400,7 @@ void SettingsTab::setDiskCachePath(const QString &path)
//****************************************************************************************************************************************************
/// \return The disk cache path.
//****************************************************************************************************************************************************
QString SettingsTab::diskCachePath() const
{
QString SettingsTab::diskCachePath() const {
return ui_.editDiskCachePath->text();
}
@ -442,8 +408,7 @@ QString SettingsTab::diskCachePath() const
//****************************************************************************************************************************************************
/// \return The value for the 'Next Cache Change Will Succeed' check box.
//****************************************************************************************************************************************************
bool SettingsTab::nextCacheChangeWillSucceed() const
{
bool SettingsTab::nextCacheChangeWillSucceed() const {
return ui_.checkNextCacheChangeWillSucceed->isChecked();
}
@ -451,8 +416,7 @@ bool SettingsTab::nextCacheChangeWillSucceed() const
//****************************************************************************************************************************************************
/// \return The index of the selected cache error.
//****************************************************************************************************************************************************
qint32 SettingsTab::cacheError() const
{
qint32 SettingsTab::cacheError() const {
return ui_.comboCacheError->currentIndex();
}
@ -460,8 +424,7 @@ qint32 SettingsTab::cacheError() const
//****************************************************************************************************************************************************
/// \return the value for the 'Automatic Update' check.
//****************************************************************************************************************************************************
bool SettingsTab::isAutomaticUpdateOn() const
{
bool SettingsTab::isAutomaticUpdateOn() const {
return ui_.checkAutomaticUpdate->isChecked();
}
@ -469,8 +432,7 @@ bool SettingsTab::isAutomaticUpdateOn() const
//****************************************************************************************************************************************************
/// \param[in] on The value for the 'Automatic Update' check.
//****************************************************************************************************************************************************
void SettingsTab::setIsAutomaticUpdateOn(bool on)
{
void SettingsTab::setIsAutomaticUpdateOn(bool on) {
ui_.checkAutomaticUpdate->setChecked(on);
}
@ -478,8 +440,7 @@ void SettingsTab::setIsAutomaticUpdateOn(bool on)
//****************************************************************************************************************************************************
//
//****************************************************************************************************************************************************
void SettingsTab::resetUI()
{
void SettingsTab::resetUI() {
this->setGUIReady(false);
this->setIsStreaming(false);
this->setClientPlatform("Unknown");
@ -503,8 +464,7 @@ void SettingsTab::resetUI()
QString const filePath = QDir(tmpDir).absoluteFilePath("LICENSE.txt");
QFile file(filePath);
if (!file.exists())
{
if (!file.exists()) {
// we don't really care if it fails.
file.open(QIODevice::WriteOnly | QIODevice::Text);
file.write(QString("This is were the license should be.").toLocal8Bit());

View File

@ -26,8 +26,7 @@
//****************************************************************************************************************************************************
/// \brief The 'General' tab of the main window.
//****************************************************************************************************************************************************
class SettingsTab : public QWidget
{
class SettingsTab : public QWidget {
Q_OBJECT
public: // member functions.
explicit SettingsTab(QWidget *parent = nullptr); ///< Default constructor.
@ -79,7 +78,7 @@ public slots:
void setColorSchemeName(QString const &name); ///< Set the value for the 'Use Dark Theme' check box.
void setBugReport(QString const &osType, QString const &osVersion, QString const &emailClient, QString const &address, QString const &description,
bool includeLogs); ///< Set the content of the bug report box.
void exportTLSCertificates(QString const& folderPath); ///< Export the TLS certificates.
void exportTLSCertificates(QString const &folderPath); ///< Export the TLS certificates.
void setMailServerSettings(qint32 imapPort, qint32 smtpPort, bool useSSLForIMAP, bool useSSLForSMTP); ///< Change the mail server settings.
void setIsDoHEnabled(bool enabled); ///< Set the value for the 'DoH Enabled' check box.
void setDiskCachePath(QString const &path); ///< Set the value for the 'Cache On Disk Enabled' check box.

View File

@ -32,15 +32,15 @@ using namespace bridgepp;
//****************************************************************************************************************************************************
UsersTab::UsersTab(QWidget *parent)
: QWidget(parent)
, users_(nullptr)
{
, users_(nullptr) {
ui_.setupUi(this);
ui_.tableUserList->setModel(&users_);
QItemSelectionModel *model = ui_.tableUserList->selectionModel();
if (!model)
if (!model) {
throw Exception("Could not get user table selection model.");
}
connect(model, &QItemSelectionModel::selectionChanged, this, &UsersTab::onSelectionChanged);
ui_.tableUserList->setColumnWidth(0, 150);
@ -62,62 +62,65 @@ UsersTab::UsersTab(QWidget *parent)
//****************************************************************************************************************************************************
//
//****************************************************************************************************************************************************
void UsersTab::onAddUserButton()
{
void UsersTab::onAddUserButton() {
SPUser user = randomUser();
UserDialog dialog(user, this);
if (QDialog::Accepted != dialog.exec())
if (QDialog::Accepted != dialog.exec()) {
return;
}
users_.append(user);
GRPCService &grpc = app().grpc();
if (grpc.isStreaming())
if (grpc.isStreaming()) {
grpc.sendEvent(newLoginFinishedEvent(user->id()));
}
}
//****************************************************************************************************************************************************
//
//****************************************************************************************************************************************************
void UsersTab::onEditUserButton()
{
void UsersTab::onEditUserButton() {
int index = selectedIndex();
if ((index < 0) || (index >= users_.userCount()))
if ((index < 0) || (index >= users_.userCount())) {
return;
}
SPUser user = this->selectedUser();
UserDialog dialog(user, this);
if (QDialog::Accepted != dialog.exec())
if (QDialog::Accepted != dialog.exec()) {
return;
}
users_.touch(index);
GRPCService &grpc = app().grpc();
if (grpc.isStreaming())
if (grpc.isStreaming()) {
grpc.sendEvent(newUserChangedEvent(user->id()));
}
}
//****************************************************************************************************************************************************
//
//****************************************************************************************************************************************************
void UsersTab::onRemoveUserButton()
{
void UsersTab::onRemoveUserButton() {
int index = selectedIndex();
if ((index < 0) || (index >= users_.userCount()))
if ((index < 0) || (index >= users_.userCount())) {
return;
}
SPUser const user = users_.userAtIndex(index);
users_.remove(index);
GRPCService &grpc = app().grpc();
if (grpc.isStreaming())
if (grpc.isStreaming()) {
grpc.sendEvent(newUserChangedEvent(user->id()));
}
}
//****************************************************************************************************************************************************
//
//****************************************************************************************************************************************************
void UsersTab::onSelectionChanged(QItemSelection, QItemSelection)
{
void UsersTab::onSelectionChanged(QItemSelection, QItemSelection) {
this->updateGUIState();
}
@ -125,8 +128,7 @@ void UsersTab::onSelectionChanged(QItemSelection, QItemSelection)
//****************************************************************************************************************************************************
//
//****************************************************************************************************************************************************
void UsersTab::updateGUIState()
{
void UsersTab::updateGUIState() {
bool const hasSelectedUser = ui_.tableUserList->selectionModel()->hasSelection();
ui_.buttonEditUser->setEnabled(hasSelectedUser);
ui_.buttonRemoveUser->setEnabled(hasSelectedUser);
@ -137,8 +139,7 @@ void UsersTab::updateGUIState()
//****************************************************************************************************************************************************
//
//****************************************************************************************************************************************************
qint32 UsersTab::selectedIndex() const
{
qint32 UsersTab::selectedIndex() const {
return ui_.tableUserList->selectionModel()->hasSelection() ? ui_.tableUserList->currentIndex().row() : -1;
}
@ -147,8 +148,7 @@ qint32 UsersTab::selectedIndex() const
/// \return The selected user.
/// \return A null pointer if no user is selected.
//****************************************************************************************************************************************************
bridgepp::SPUser UsersTab::selectedUser()
{
bridgepp::SPUser UsersTab::selectedUser() {
return users_.userAtIndex(this->selectedIndex());
}
@ -156,8 +156,7 @@ bridgepp::SPUser UsersTab::selectedUser()
//****************************************************************************************************************************************************
/// \return The list of users.
//****************************************************************************************************************************************************
UserTable &UsersTab::userTable()
{
UserTable &UsersTab::userTable() {
return users_;
}
@ -167,8 +166,7 @@ UserTable &UsersTab::userTable()
/// \return The user with the given userID.
/// \return A null pointer if the user is not in the list.
//****************************************************************************************************************************************************
bridgepp::SPUser UsersTab::userWithID(QString const &userID)
{
bridgepp::SPUser UsersTab::userWithID(QString const &userID) {
return users_.userWithID(userID);
}
@ -176,8 +174,7 @@ bridgepp::SPUser UsersTab::userWithID(QString const &userID)
//****************************************************************************************************************************************************
/// \return true iff the next login attempt should trigger a username/password error.
//****************************************************************************************************************************************************
bool UsersTab::nextUserUsernamePasswordError() const
{
bool UsersTab::nextUserUsernamePasswordError() const {
return ui_.checkUsernamePasswordError->isChecked();
}
@ -185,8 +182,7 @@ bool UsersTab::nextUserUsernamePasswordError() const
//****************************************************************************************************************************************************
/// \return true iff the next login attempt should trigger a free user error.
//****************************************************************************************************************************************************
bool UsersTab::nextUserFreeUserError() const
{
bool UsersTab::nextUserFreeUserError() const {
return ui_.checkFreeUserError->isChecked();
}
@ -194,8 +190,7 @@ bool UsersTab::nextUserFreeUserError() const
//****************************************************************************************************************************************************
/// \return true iff the next login attempt will require 2FA.
//****************************************************************************************************************************************************
bool UsersTab::nextUserTFARequired() const
{
bool UsersTab::nextUserTFARequired() const {
return ui_.checkTFARequired->isChecked();
}
@ -203,8 +198,7 @@ bool UsersTab::nextUserTFARequired() const
//****************************************************************************************************************************************************
/// \return true iff the next login attempt should trigger a 2FA error.
//****************************************************************************************************************************************************
bool UsersTab::nextUserTFAError() const
{
bool UsersTab::nextUserTFAError() const {
return ui_.checkTFAError->isChecked();
}
@ -212,8 +206,7 @@ bool UsersTab::nextUserTFAError() const
//****************************************************************************************************************************************************
/// \return true iff the next login attempt should trigger a 2FA error with abort.
//****************************************************************************************************************************************************
bool UsersTab::nextUserTFAAbort() const
{
bool UsersTab::nextUserTFAAbort() const {
return ui_.checkTFAAbort->isChecked();
}
@ -221,8 +214,7 @@ bool UsersTab::nextUserTFAAbort() const
//****************************************************************************************************************************************************
/// \return true iff the next login attempt will require a 2nd password.
//****************************************************************************************************************************************************
bool UsersTab::nextUserTwoPasswordsRequired() const
{
bool UsersTab::nextUserTwoPasswordsRequired() const {
return ui_.checkTwoPasswordsRequired->isChecked();
}
@ -230,8 +222,7 @@ bool UsersTab::nextUserTwoPasswordsRequired() const
//****************************************************************************************************************************************************
/// \return true iff the next login attempt should trigger a 2nd password error.
//****************************************************************************************************************************************************
bool UsersTab::nextUserTwoPasswordsError() const
{
bool UsersTab::nextUserTwoPasswordsError() const {
return ui_.checkTwoPasswordsError->isChecked();
}
@ -239,8 +230,7 @@ bool UsersTab::nextUserTwoPasswordsError() const
//****************************************************************************************************************************************************
/// \return true iff the next login attempt should trigger a 2nd password error with abort.
//****************************************************************************************************************************************************
bool UsersTab::nextUserTwoPasswordsAbort() const
{
bool UsersTab::nextUserTwoPasswordsAbort() const {
return ui_.checkTwoPasswordsAbort->isChecked();
}
@ -248,8 +238,7 @@ bool UsersTab::nextUserTwoPasswordsAbort() const
//****************************************************************************************************************************************************
/// \return true iff the next login attempt should trigger a 2nd password error with abort.
//****************************************************************************************************************************************************
bool UsersTab::nextUserAlreadyLoggedIn() const
{
bool UsersTab::nextUserAlreadyLoggedIn() const {
return ui_.checkAlreadyLoggedIn->isChecked();
}
@ -257,8 +246,7 @@ bool UsersTab::nextUserAlreadyLoggedIn() const
//****************************************************************************************************************************************************
/// \return the message for the username/password error.
//****************************************************************************************************************************************************
QString UsersTab::usernamePasswordErrorMessage() const
{
QString UsersTab::usernamePasswordErrorMessage() const {
return ui_.editUsernamePasswordError->text();
}
@ -267,12 +255,10 @@ QString UsersTab::usernamePasswordErrorMessage() const
/// \param[in] userID The userID.
/// \param[in] makeItActive Should split mode be activated.
//****************************************************************************************************************************************************
void UsersTab::setUserSplitMode(QString const &userID, bool makeItActive)
{
void UsersTab::setUserSplitMode(QString const &userID, bool makeItActive) {
qint32 const index = users_.indexOfUser(userID);
SPUser const user = users_.userAtIndex(index);
if (!user)
{
if (!user) {
app().log().error(QString("%1 failed. unknown user %1").arg(__FUNCTION__, userID));
return;
}
@ -283,15 +269,14 @@ void UsersTab::setUserSplitMode(QString const &userID, bool makeItActive)
mainWindow.sendDelayedEvent(newToggleSplitModeFinishedEvent(userID));
}
//****************************************************************************************************************************************************
/// \param[in] userID The userID.
//****************************************************************************************************************************************************
void UsersTab::logoutUser(QString const &userID)
{
void UsersTab::logoutUser(QString const &userID) {
qint32 const index = users_.indexOfUser(userID);
SPUser const user = users_.userAtIndex(index);
if (!user)
{
if (!user) {
app().log().error(QString("%1 failed. unknown user %1").arg(__FUNCTION__, userID));
return;
}
@ -304,12 +289,10 @@ void UsersTab::logoutUser(QString const &userID)
//****************************************************************************************************************************************************
/// \param[in] userID The userID.
//****************************************************************************************************************************************************
void UsersTab::removeUser(QString const &userID)
{
void UsersTab::removeUser(QString const &userID) {
qint32 const index = users_.indexOfUser(userID);
SPUser const user = users_.userAtIndex(index);
if (!user)
{
if (!user) {
app().log().error(QString("%1 failed. unknown user %1").arg(__FUNCTION__, userID));
return;
}
@ -322,8 +305,7 @@ void UsersTab::removeUser(QString const &userID)
/// \param[in] userID The userID.
/// \param[in] address The address.
//****************************************************************************************************************************************************
void UsersTab::configureUserAppleMail(QString const &userID, QString const &address)
{
void UsersTab::configureUserAppleMail(QString const &userID, QString const &address) {
app().log().info(QString("Apple mail configuration was requested for user %1, address %2").arg(userID, address));
}

View File

@ -27,8 +27,7 @@
//****************************************************************************************************************************************************
/// \brief The 'Users' tab of the main window.
//****************************************************************************************************************************************************
class UsersTab : public QWidget
{
class UsersTab : public QWidget {
Q_OBJECT
public: // member functions.
explicit UsersTab(QWidget *parent = nullptr); ///< Default constructor.

View File

@ -28,8 +28,7 @@ using namespace bridgepp;
//****************************************************************************************************************************************************
UserDialog::UserDialog(bridgepp::SPUser &user, QWidget *parent)
: QDialog(parent)
, user_(user)
{
, user_(user) {
ui_.setupUi(this);
connect(ui_.buttonOK, &QPushButton::clicked, this, &UserDialog::onOK);
@ -51,8 +50,7 @@ UserDialog::UserDialog(bridgepp::SPUser &user, QWidget *parent)
//****************************************************************************************************************************************************
//
//****************************************************************************************************************************************************
void UserDialog::onOK()
{
void UserDialog::onOK() {
user_->setID(ui_.editUserID->text());
user_->setUsername(ui_.editUsername->text());
user_->setPassword(ui_.editPassword->text());
@ -71,8 +69,7 @@ void UserDialog::onOK()
//****************************************************************************************************************************************************
/// \return The user state that is currently selected in the dialog.
//****************************************************************************************************************************************************
UserState UserDialog::state()
{
UserState UserDialog::state() {
return UserState(ui_.comboState->currentIndex());
}
@ -80,7 +77,6 @@ UserState UserDialog::state()
//****************************************************************************************************************************************************
/// \param[in] state The user state to select in the dialog.
//****************************************************************************************************************************************************
void UserDialog::setState(UserState state)
{
void UserDialog::setState(UserState state) {
ui_.comboState->setCurrentIndex(qint32(state));
}

View File

@ -23,11 +23,11 @@
#include "ui_UserDialog.h"
#include <bridgepp/User/User.h>
//****************************************************************************************************************************************************
/// \brief User dialog class.
//****************************************************************************************************************************************************
class UserDialog : public QDialog
{
class UserDialog : public QDialog {
Q_OBJECT
public: // member functions.
UserDialog(bridgepp::SPUser &user, QWidget *parent); ///< Default constructor.

View File

@ -26,8 +26,7 @@ using namespace bridgepp;
/// \param[in] parent The parent object of the class
//****************************************************************************************************************************************************
UserTable::UserTable(QObject *parent)
: QAbstractTableModel(parent)
{
: QAbstractTableModel(parent) {
}
@ -35,8 +34,7 @@ UserTable::UserTable(QObject *parent)
//****************************************************************************************************************************************************
/// \return The number of rows in the table.
//****************************************************************************************************************************************************
int UserTable::rowCount(QModelIndex const &) const
{
int UserTable::rowCount(QModelIndex const &) const {
return users_.size();
}
@ -44,8 +42,7 @@ int UserTable::rowCount(QModelIndex const &) const
//****************************************************************************************************************************************************
/// \return The number of columns in the table.
//****************************************************************************************************************************************************
int UserTable::columnCount(QModelIndex const &) const
{
int UserTable::columnCount(QModelIndex const &) const {
return 4;
}
@ -55,18 +52,18 @@ int UserTable::columnCount(QModelIndex const &) const
/// \param[in] role The role to retrieve data for.
/// \return The data for the role at the given index.
//****************************************************************************************************************************************************
QVariant UserTable::data(QModelIndex const &index, int role) const
{
QVariant UserTable::data(QModelIndex const &index, int role) const {
int const row = index.row();
if ((row < 0) || (row >= users_.size()) || (Qt::DisplayRole != role))
if ((row < 0) || (row >= users_.size()) || (Qt::DisplayRole != role)) {
return QVariant();
}
SPUser const user = users_[row];
if (!user)
if (!user) {
return QVariant();
}
switch (index.column())
{
switch (index.column()) {
case 0:
return user->property("username");
case 1:
@ -86,16 +83,16 @@ QVariant UserTable::data(QModelIndex const &index, int role) const
/// \param[in] orientation The orientation.
/// \param[in] role The role to retrieve data
//****************************************************************************************************************************************************
QVariant UserTable::headerData(int section, Qt::Orientation orientation, int role) const
{
if (Qt::DisplayRole != role)
QVariant UserTable::headerData(int section, Qt::Orientation orientation, int role) const {
if (Qt::DisplayRole != role) {
return QAbstractTableModel::headerData(section, orientation, role);
}
if (Qt::Horizontal != orientation)
if (Qt::Horizontal != orientation) {
return QString();
}
switch (section)
{
switch (section) {
case 0:
return "UserName";
case 1:
@ -113,8 +110,7 @@ QVariant UserTable::headerData(int section, Qt::Orientation orientation, int rol
//****************************************************************************************************************************************************
/// \param[in] user The user to add.
//****************************************************************************************************************************************************
void UserTable::append(SPUser const &user)
{
void UserTable::append(SPUser const &user) {
qint32 const count = users_.size();
this->beginInsertRows(QModelIndex(), count, count);
users_.append(user);
@ -125,8 +121,7 @@ void UserTable::append(SPUser const &user)
//****************************************************************************************************************************************************
/// \return The number of users in the table.
//****************************************************************************************************************************************************
qint32 UserTable::userCount() const
{
qint32 UserTable::userCount() const {
return users_.count();
}
@ -136,8 +131,7 @@ qint32 UserTable::userCount() const
/// \return the user at the given index.
/// \return null if the index is out of bounds.
//****************************************************************************************************************************************************
bridgepp::SPUser UserTable::userAtIndex(qint32 index)
{
bridgepp::SPUser UserTable::userAtIndex(qint32 index) {
return isIndexValid(index) ? users_[index] : nullptr;
}
@ -146,9 +140,8 @@ bridgepp::SPUser UserTable::userAtIndex(qint32 index)
/// \return The user with the given userID.
/// \return A null pointer if the user is not in the list.
//****************************************************************************************************************************************************
bridgepp::SPUser UserTable::userWithID(QString const &userID)
{
QList<SPUser>::const_iterator it = std::find_if(users_.constBegin(), users_.constEnd(), [&userID](SPUser const& user) -> bool {
bridgepp::SPUser UserTable::userWithID(QString const &userID) {
QList<SPUser>::const_iterator it = std::find_if(users_.constBegin(), users_.constEnd(), [&userID](SPUser const &user) -> bool {
return user->id() == userID;
});
@ -161,9 +154,8 @@ bridgepp::SPUser UserTable::userWithID(QString const &userID)
/// \return the index of the user.
/// \return -1 if the user could not be found.
//****************************************************************************************************************************************************
qint32 UserTable::indexOfUser(QString const &userID)
{
QList<SPUser>::const_iterator it = std::find_if(users_.constBegin(), users_.constEnd(), [&userID](SPUser const& user) -> bool {
qint32 UserTable::indexOfUser(QString const &userID) {
QList<SPUser>::const_iterator it = std::find_if(users_.constBegin(), users_.constEnd(), [&userID](SPUser const &user) -> bool {
return user->id() == userID;
});
@ -174,20 +166,19 @@ qint32 UserTable::indexOfUser(QString const &userID)
//****************************************************************************************************************************************************
/// \param[in] index The index of the user in the list.
//****************************************************************************************************************************************************
void UserTable::touch(qint32 index)
{
void UserTable::touch(qint32 index) {
if (isIndexValid(index))
emit dataChanged(this->index(index, 0), this->index(index, this->columnCount(QModelIndex()) - 1));
emit { dataChanged(this->index(index, 0), this->index(index, this->columnCount(QModelIndex()) - 1)); }
}
//****************************************************************************************************************************************************
/// \param[in] index The index of the user in the list.
//****************************************************************************************************************************************************
void UserTable::remove(qint32 index)
{
if (!isIndexValid(index))
void UserTable::remove(qint32 index) {
if (!isIndexValid(index)) {
return;
}
this->beginRemoveRows(QModelIndex(), index, index);
users_.removeAt(index);
@ -198,8 +189,7 @@ void UserTable::remove(qint32 index)
//****************************************************************************************************************************************************
/// \return true iff the index is valid.
//****************************************************************************************************************************************************
bool UserTable::isIndexValid(qint32 index) const
{
bool UserTable::isIndexValid(qint32 index) const {
return (index >= 0) && (index < users_.count());
}
@ -207,7 +197,6 @@ bool UserTable::isIndexValid(qint32 index) const
//****************************************************************************************************************************************************
/// \return The user list.
//****************************************************************************************************************************************************
QList<bridgepp::SPUser> UserTable::users() const
{
QList<bridgepp::SPUser> UserTable::users() const {
return users_;
}

View File

@ -27,8 +27,7 @@
/// \brief User table model class
//****************************************************************************************************************************************************
class UserTable : public QAbstractTableModel
{
class UserTable : public QAbstractTableModel {
Q_OBJECT
public: // member functions.
explicit UserTable(QObject *parent); ///< Default constructor.
@ -38,10 +37,10 @@ public: // member functions.
UserTable &operator=(UserTable const &) = delete; ///< Disabled assignment operator.
UserTable &operator=(UserTable &&) = delete; ///< Disabled move assignment operator.
qint32 userCount() const; ///< Return the number of users in the table.
void append(bridgepp::SPUser const& user); ///< Append a user.
void append(bridgepp::SPUser const &user); ///< Append a user.
bridgepp::SPUser userAtIndex(qint32 index); ///< Return the user at the given index.
bridgepp::SPUser userWithID(QString const &userID); ///< Return the user with a given id.
qint32 indexOfUser(QString const& userID); ///< Return the index of a given User.
qint32 indexOfUser(QString const &userID); ///< Return the index of a given User.
void touch(qint32 index); ///< touch the user at a given index (indicates it has been modified).
void remove(qint32 index); ///< Remove the user at a given index.
QList<bridgepp::SPUser> users() const; ///< Return a copy of the user list.

View File

@ -28,8 +28,7 @@
#endif
namespace
{
namespace {
QString const applicationName = "Proton Mail Bridge GUI Tester"; ///< The name of the application.
@ -46,18 +45,16 @@ using namespace bridgepp;
/// \param[in] argv The list of command-line arguments.
/// \return The exit code for the application.
//****************************************************************************************************************************************************
int main(int argc, char **argv)
{
int main(int argc, char **argv) {
try
{
try {
QApplication a(argc, argv);
QApplication::setApplicationName(applicationName);
QApplication::setOrganizationName("Proton AG");
QApplication::setOrganizationDomain("proton.ch");
QApplication::setQuitOnLastWindowClosed(true);
Log& log = app().log();
Log &log = app().log();
log.setEchoInConsole(true);
log.setLevel(Log::Level::Debug);
log.info(QString("%1 started.").arg(applicationName));
@ -70,21 +67,24 @@ int main(int argc, char **argv)
auto *serverWorker = new GRPCServerWorker(nullptr);
QObject::connect(serverWorker, &Worker::started, []() { app().log().info("Server worker started."); });
QObject::connect(serverWorker, &Worker::finished, []() { app().log().info("Server worker finished."); });
QObject::connect(serverWorker, &Worker::error, [&](QString const &message) { app().log().error(message); qApp->exit(EXIT_FAILURE); });
QObject::connect(serverWorker, &Worker::error, [&](QString const &message) {
app().log().error(message);
qApp->exit(EXIT_FAILURE);
});
UPOverseer overseer = std::make_unique<Overseer>(serverWorker, nullptr);
overseer->startWorker(true);
qint32 const exitCode = QApplication::exec();
serverWorker->stop();
if (!overseer->wait(5000))
if (!overseer->wait(5000)) {
log.warn("gRPC server took too long to finish.");
}
app().log().info(QString("%1 exiting with code %2.").arg(applicationName).arg(exitCode));
return exitCode;
}
catch (Exception const &e)
{
catch (Exception const &e) {
QTextStream(stderr) << QString("A fatal error occurred: %1\n").arg(e.qwhat());
return EXIT_FAILURE;
}

View File

@ -30,8 +30,7 @@ using namespace bridgepp;
//****************************************************************************************************************************************************
/// \return The AppController instance.
//****************************************************************************************************************************************************
AppController &app()
{
AppController &app() {
static AppController app;
return app;
}
@ -43,24 +42,24 @@ AppController &app()
AppController::AppController()
: backend_(std::make_unique<QMLBackend>())
, grpc_(std::make_unique<GRPCClient>())
, log_(std::make_unique<Log>())
{
, log_(std::make_unique<Log>()) {
}
//****************************************************************************************************************************************************
/// \return The bridge worker, which can be null if the application was run in 'attach' mode (-a command-line switch).
//****************************************************************************************************************************************************
ProcessMonitor *AppController::bridgeMonitor() const
{
if (!bridgeOverseer_)
ProcessMonitor *AppController::bridgeMonitor() const {
if (!bridgeOverseer_) {
return nullptr;
}
// null bridgeOverseer is OK, it means we run in 'attached' mode (app attached to an already runnning instance of Bridge).
// but if bridgeOverseer is not null, its attached worker must be a valid ProcessMonitor instance.
auto *monitor = dynamic_cast<ProcessMonitor*>(bridgeOverseer_->worker());
if (!monitor)
auto *monitor = dynamic_cast<ProcessMonitor *>(bridgeOverseer_->worker());
if (!monitor) {
throw Exception("Could not retrieve bridge monitor");
}
return monitor;
}

View File

@ -23,11 +23,16 @@
class QMLBackend;
namespace bridgepp
{
namespace bridgepp {
class Log;
class Overseer;
class GRPCClient;
class ProcessMonitor;
}
@ -35,22 +40,21 @@ class ProcessMonitor;
//****************************************************************************************************************************************************
/// \brief App controller class.
//****************************************************************************************************************************************************
class AppController: public QObject
{
Q_OBJECT
friend AppController& app();
class AppController : public QObject {
Q_OBJECT
friend AppController &app();
public: // member functions.
AppController(AppController const&) = delete; ///< Disabled copy-constructor.
AppController(AppController&&) = delete; ///< Disabled assignment copy-constructor.
AppController(AppController const &) = delete; ///< Disabled copy-constructor.
AppController(AppController &&) = delete; ///< Disabled assignment copy-constructor.
~AppController() override = default; ///< Destructor.
AppController& operator=(AppController const&) = delete; ///< Disabled assignment operator.
AppController& operator=(AppController&&) = delete; ///< Disabled move assignment operator.
QMLBackend& backend() { return *backend_; } ///< Return a reference to the backend.
bridgepp::GRPCClient& grpc() { return *grpc_; } ///< Return a reference to the GRPC client.
bridgepp::Log& log() { return *log_; } ///< Return a reference to the log.
std::unique_ptr<bridgepp::Overseer>& bridgeOverseer() { return bridgeOverseer_; }; ///< Returns a reference the bridge overseer
bridgepp::ProcessMonitor* bridgeMonitor() const; ///< Return the bridge worker.
AppController &operator=(AppController const &) = delete; ///< Disabled assignment operator.
AppController &operator=(AppController &&) = delete; ///< Disabled move assignment operator.
QMLBackend &backend() { return *backend_; } ///< Return a reference to the backend.
bridgepp::GRPCClient &grpc() { return *grpc_; } ///< Return a reference to the GRPC client.
bridgepp::Log &log() { return *log_; } ///< Return a reference to the log.
std::unique_ptr<bridgepp::Overseer> &bridgeOverseer() { return bridgeOverseer_; }; ///< Returns a reference the bridge overseer
bridgepp::ProcessMonitor *bridgeMonitor() const; ///< Return the bridge worker.
private: // member functions
AppController(); ///< Default constructor.
@ -63,7 +67,7 @@ private: // data members
};
AppController& app(); ///< Return a reference to the app controller.
AppController &app(); ///< Return a reference to the app controller.
#endif // BRIDGE_GUI_APP_CONTROLLER_H

View File

@ -23,8 +23,7 @@
using namespace bridgepp;
namespace
{
namespace {
QString const launcherFlag = "--launcher"; ///< launcher flag parameter used for bridge.
@ -37,25 +36,25 @@ QString const softwareRendererFlag = "--software-renderer"; ///< The 'software-r
/// \param[in] argv The list of arguments passed to the application.
/// \param[in] paramNames the list of names for the parameter
//****************************************************************************************************************************************************
QString parseGoCLIStringArgument(int argc, char *argv[], QStringList paramNames)
{
QString parseGoCLIStringArgument(int argc, char *argv[], QStringList paramNames) {
// go cli package is pretty permissive when it comes to parsing arguments. For each name 'param', all the following seems to be accepted:
// -param value
// --param value
// -param=value
// --param=value
for (QString const &paramName: paramNames)
for (qsizetype i = 1; i < argc; ++i)
{
for (QString const &paramName: paramNames) {
for (qsizetype i = 1; i < argc; ++i) {
QString const arg(QString::fromLocal8Bit(argv[i]));
if ((i < argc - 1) && ((arg == "-" + paramName) || (arg == "--" + paramName)))
if ((i < argc - 1) && ((arg == "-" + paramName) || (arg == "--" + paramName))) {
return QString(argv[i + 1]);
}
QRegularExpressionMatch match = QRegularExpression(QString("^-{1,2}%1=(.+)$").arg(paramName)).match(arg);
if (match.hasMatch())
if (match.hasMatch()) {
return match.captured(1);
}
}
}
return QString();
}
@ -68,11 +67,11 @@ QString parseGoCLIStringArgument(int argc, char *argv[], QStringList paramNames)
/// \param[in] argv The list of arguments passed to the application.
/// \return The log level. if not specified on the command-line, the default log level is returned.
//****************************************************************************************************************************************************
Log::Level parseLogLevel(int argc, char *argv[])
{
Log::Level parseLogLevel(int argc, char *argv[]) {
QString levelStr = parseGoCLIStringArgument(argc, argv, { "l", "log-level" });
if (levelStr.isEmpty())
if (levelStr.isEmpty()) {
return Log::defaultLevel;
}
Log::Level level = Log::defaultLevel;
Log::stringToLevel(levelStr, level);
@ -98,33 +97,29 @@ CommandLineOptions parseCommandLine(int argc, char *argv[]) {
QString const &arg = QString::fromLocal8Bit(argv[i]);
// we can't use QCommandLineParser here since it will fail on unknown options.
// Arguments may contain some bridge flags.
if (arg == softwareRendererFlag)
if (arg == softwareRendererFlag) {
options.useSoftwareRenderer = true;
if (arg == noWindowFlag)
{
}
if (arg == noWindowFlag) {
options.noWindow = true;
}
if (arg == launcherFlag)
{
if (arg == launcherFlag) {
options.bridgeArgs.append(arg);
options.launcher = QString::fromLocal8Bit(argv[++i]);
options.bridgeArgs.append(options.launcher);
flagFound = true;
}
#ifdef QT_DEBUG
else if (arg == "--attach" || arg == "-a")
{
else if (arg == "--attach" || arg == "-a") {
// we don't keep the attach mode within the args since we don't need it for Bridge.
options.attach = true;
}
#endif
else
{
else {
options.bridgeArgs.append(arg);
}
}
if (!flagFound)
{
if (!flagFound) {
// add bridge-gui as launcher
options.bridgeArgs.append(launcherFlag);
options.bridgeArgs.append(options.launcher);

View File

@ -22,6 +22,8 @@
void setDockIconVisibleState(bool visible) { Q_UNUSED(visible) }
bool getDockIconVisibleState() { return true; }

View File

@ -30,8 +30,7 @@ using namespace bridgepp;
/// \param[in] parent The parent object.
//****************************************************************************************************************************************************
EventStreamReader::EventStreamReader(QObject *parent)
: Worker(parent)
{
: Worker(parent) {
connect(this, &EventStreamReader::started, this, &EventStreamReader::onStarted);
connect(this, &EventStreamReader::finished, this, &EventStreamReader::onFinished);
connect(this, &EventStreamReader::error, &app().log(), &Log::error);
@ -41,20 +40,18 @@ EventStreamReader::EventStreamReader(QObject *parent)
//****************************************************************************************************************************************************
//
//****************************************************************************************************************************************************
void EventStreamReader::run()
{
try
{
void EventStreamReader::run() {
try {
emit started();
grpc::Status const status = app().grpc().runEventStreamReader();
if (!status.ok())
if (!status.ok()) {
throw Exception(QString::fromStdString(status.error_message()));
}
emit finished();
}
catch (Exception const &e)
{
catch (Exception const &e) {
reportSentryException(SENTRY_LEVEL_ERROR, "Error during event stream read", "Exception", e.what());
emit error(e.qwhat());
}
@ -64,8 +61,7 @@ void EventStreamReader::run()
//****************************************************************************************************************************************************
//
//****************************************************************************************************************************************************
void EventStreamReader::onStarted() const
{
void EventStreamReader::onStarted() const {
app().log().debug("EventStreamReader started");
}
@ -73,11 +69,9 @@ void EventStreamReader::onStarted() const
//****************************************************************************************************************************************************
//
//****************************************************************************************************************************************************
void EventStreamReader::onFinished() const
{
void EventStreamReader::onFinished() const {
app().log().debug("EventStreamReader finished");
if (!app().bridgeMonitor())
{
if (!app().bridgeMonitor()) {
// no bridge monitor means we are in a debug environment, running in attached mode. Event stream has terminated, so bridge is shutting
// down. Because we're in attached mode, bridge-gui will not get notified that bridge is going down, so we shutdown manually here.
qApp->exit(EXIT_SUCCESS);

View File

@ -26,16 +26,15 @@
//****************************************************************************************************************************************************
/// \brief Stream reader class.
//****************************************************************************************************************************************************
class EventStreamReader: public bridgepp::Worker
{
Q_OBJECT
class EventStreamReader : public bridgepp::Worker {
Q_OBJECT
public: // member functions
explicit EventStreamReader(QObject *parent); ///< Default constructor.
EventStreamReader(EventStreamReader const&) = delete; ///< Disabled copy-constructor.
EventStreamReader(EventStreamReader&&) = delete; ///< Disabled assignment copy-constructor.
EventStreamReader(EventStreamReader const &) = delete; ///< Disabled copy-constructor.
EventStreamReader(EventStreamReader &&) = delete; ///< Disabled assignment copy-constructor.
~EventStreamReader() override = default; ///< Destructor.
EventStreamReader& operator=(EventStreamReader const&) = delete; ///< Disabled assignment operator.
EventStreamReader& operator=(EventStreamReader&&) = delete; ///< Disabled move assignment operator.
EventStreamReader &operator=(EventStreamReader const &) = delete; ///< Disabled assignment operator.
EventStreamReader &operator=(EventStreamReader &&) = delete; ///< Disabled move assignment operator.
public slots:
void run() override; ///< Run the reader.

View File

@ -31,38 +31,38 @@ using namespace bridgepp;
//
//****************************************************************************************************************************************************
QMLBackend::QMLBackend()
: QObject()
{
: QObject() {
}
//****************************************************************************************************************************************************
/// \param[in] serviceConfig
//****************************************************************************************************************************************************
void QMLBackend::init(GRPCConfig const &serviceConfig)
{
void QMLBackend::init(GRPCConfig const &serviceConfig) {
users_ = new UserList(this);
Log& log = app().log();
Log &log = app().log();
log.info(QString("Connecting to gRPC service"));
app().grpc().setLog(&log);
this->connectGrpcEvents();
QString error;
if (app().grpc().connectToServer(serviceConfig, app().bridgeMonitor(), error))
if (app().grpc().connectToServer(serviceConfig, app().bridgeMonitor(), error)) {
app().log().info("Connected to backend via gRPC service.");
else
} else {
throw Exception(QString("Cannot connectToServer to go backend via gRPC: %1").arg(error));
}
QString bridgeVer;
app().grpc().version(bridgeVer);
if (bridgeVer != PROJECT_VER)
if (bridgeVer != PROJECT_VER) {
throw Exception(QString("Version Mismatched from Bridge (%1) and Bridge-GUI (%2)").arg(bridgeVer, PROJECT_VER));
}
eventStreamOverseer_ = std::make_unique<Overseer>(new EventStreamReader(nullptr), nullptr);
eventStreamOverseer_->startWorker(true);
connect(&app().log(), &Log::entryAdded, [&](Log::Level level, QString const& message) {
connect(&app().log(), &Log::entryAdded, [&](Log::Level level, QString const &message) {
app().grpc().addLogEntry(level, "frontend/bridge-gui", message);
});
@ -87,8 +87,7 @@ void QMLBackend::init(GRPCConfig const &serviceConfig)
/// never times out.
/// \return false if and only if the timeout delay was reached.
//****************************************************************************************************************************************************
bool QMLBackend::waitForEventStreamReaderToFinish(qint32 timeoutMs)
{
bool QMLBackend::waitForEventStreamReaderToFinish(qint32 timeoutMs) {
return eventStreamOverseer_->wait(timeoutMs);
}
@ -96,12 +95,11 @@ bool QMLBackend::waitForEventStreamReaderToFinish(qint32 timeoutMs)
//****************************************************************************************************************************************************
//
//****************************************************************************************************************************************************
void QMLBackend::connectGrpcEvents()
{
void QMLBackend::connectGrpcEvents() {
GRPCClient *client = &app().grpc();
// app events
connect(client, &GRPCClient::internetStatus, this, [&](bool isOn) { if (isOn) emit internetOn(); else emit internetOff(); });
connect(client, &GRPCClient::internetStatus, this, [&](bool isOn) { if (isOn) { emit internetOn(); } else { emit internetOff(); }});
connect(client, &GRPCClient::toggleAutostartFinished, this, &QMLBackend::toggleAutostartFinished);
connect(client, &GRPCClient::resetFinished, this, &QMLBackend::onResetFinished);
connect(client, &GRPCClient::reportBugFinished, this, &QMLBackend::reportBugFinished);
@ -174,8 +172,7 @@ void QMLBackend::connectGrpcEvents()
//****************************************************************************************************************************************************
//
//****************************************************************************************************************************************************
void QMLBackend::retrieveUserList()
{
void QMLBackend::retrieveUserList() {
QList<SPUser> newUsers;
app().grpc().getUserList(newUsers);
@ -184,23 +181,22 @@ void QMLBackend::retrieveUserList()
// " When data is transferred from C++ to QML, the ownership of the data always remains with C++. The exception to this rule
// is when a QObject is returned from an explicit C++ method call: in this case, the QML engine assumes ownership of the object. "
// This is the case here, so we explicitly indicate that the object is owned by C++.
for (SPUser const& user: newUsers)
for (SPUser const &user: newUsers) {
for (qsizetype i = 0; i < newUsers.size(); ++i)
{
SPUser newUser = newUsers[i];
SPUser existingUser = users_->getUserWithID(newUser->id());
if (!existingUser)
{
// The user is new. We indicate to QML that it is managed by the C++ backend.
QQmlEngine::setObjectOwnership(user.get(), QQmlEngine::CppOwnership);
continue;
for (qsizetype i = 0; i < newUsers.size(); ++i) {
SPUser newUser = newUsers[i];
SPUser existingUser = users_->getUserWithID(newUser->id());
if (!existingUser) {
// The user is new. We indicate to QML that it is managed by the C++ backend.
QQmlEngine::setObjectOwnership(user.get(), QQmlEngine::CppOwnership);
continue;
}
// The user is already listed. QML code may have a pointer because of an ongoing process (for instance in the SetupGuide),
// As a consequence we do not want to replace this existing user, but we want to update it.
existingUser->update(*newUser);
newUsers[i] = existingUser;
}
// The user is already listed. QML code may have a pointer because of an ongoing process (for instance in the SetupGuide),
// As a consequence we do not want to replace this existing user, but we want to update it.
existingUser->update(*newUser);
newUsers[i] = existingUser;
}
users_->reset(newUsers);
@ -210,8 +206,7 @@ void QMLBackend::retrieveUserList()
//****************************************************************************************************************************************************
//
//****************************************************************************************************************************************************
QPoint QMLBackend::getCursorPos()
{
QPoint QMLBackend::getCursorPos() {
return QCursor::pos();
}
@ -219,8 +214,7 @@ QPoint QMLBackend::getCursorPos()
//****************************************************************************************************************************************************
//
//****************************************************************************************************************************************************
bool QMLBackend::isPortFree(int port)
{
bool QMLBackend::isPortFree(int port) {
bool isFree = false;
app().grpc().isPortFree(port, isFree);
return isFree;
@ -230,8 +224,7 @@ bool QMLBackend::isPortFree(int port)
//****************************************************************************************************************************************************
/// \return true the native local file path of the given URL.
//****************************************************************************************************************************************************
QString QMLBackend::nativePath(QUrl const &url)
{
QString QMLBackend::nativePath(QUrl const &url) {
return QDir::toNativeSeparators(url.toLocalFile());
}
@ -239,8 +232,7 @@ QString QMLBackend::nativePath(QUrl const &url)
//****************************************************************************************************************************************************
/// \return true iff the two URL point to the same local file or folder.
//****************************************************************************************************************************************************
bool QMLBackend::areSameFileOrFolder(QUrl const &lhs, QUrl const &rhs)
{
bool QMLBackend::areSameFileOrFolder(QUrl const &lhs, QUrl const &rhs) {
return QFileInfo(lhs.toLocalFile()) == QFileInfo(rhs.toLocalFile());
}
@ -248,8 +240,7 @@ bool QMLBackend::areSameFileOrFolder(QUrl const &lhs, QUrl const &rhs)
//****************************************************************************************************************************************************
//
//****************************************************************************************************************************************************
void QMLBackend::guiReady()
{
void QMLBackend::guiReady() {
app().grpc().guiReady();
}
@ -257,8 +248,7 @@ void QMLBackend::guiReady()
//****************************************************************************************************************************************************
//
//****************************************************************************************************************************************************
void QMLBackend::quit()
{
void QMLBackend::quit() {
app().grpc().quit();
qApp->exit(0);
}
@ -267,8 +257,7 @@ void QMLBackend::quit()
//****************************************************************************************************************************************************
//
//****************************************************************************************************************************************************
void QMLBackend::restart()
{
void QMLBackend::restart() {
app().grpc().restart();
}
@ -276,8 +265,7 @@ void QMLBackend::restart()
//****************************************************************************************************************************************************
/// \param[in] launcher The path to the launcher.
//****************************************************************************************************************************************************
void QMLBackend::forceLauncher(QString launcher)
{
void QMLBackend::forceLauncher(QString launcher) {
app().grpc().forceLauncher(launcher);
}
@ -285,8 +273,7 @@ void QMLBackend::forceLauncher(QString launcher)
//****************************************************************************************************************************************************
/// \param[in] active Should we activate autostart.
//****************************************************************************************************************************************************
void QMLBackend::toggleAutostart(bool active)
{
void QMLBackend::toggleAutostart(bool active) {
app().grpc().setIsAutostartOn(active);
emit isAutostartOnChanged(this->isAutostartOn());
}
@ -295,17 +282,16 @@ void QMLBackend::toggleAutostart(bool active)
//****************************************************************************************************************************************************
/// \param[in] active The new state for the beta enabled property.
//****************************************************************************************************************************************************
void QMLBackend::toggleBeta(bool active)
{
void QMLBackend::toggleBeta(bool active) {
app().grpc().setIsBetaEnabled(active);
emit isBetaEnabledChanged(this->isBetaEnabled());
}
//****************************************************************************************************************************************************
/// \param[in] active The new state for the All Mail visibility property.
//****************************************************************************************************************************************************
void QMLBackend::changeIsAllMailVisible(bool isVisible)
{
void QMLBackend::changeIsAllMailVisible(bool isVisible) {
app().grpc().setIsAllMailVisible(isVisible);
emit isAllMailVisibleChanged(this->isAllMailVisible());
}
@ -314,17 +300,16 @@ void QMLBackend::changeIsAllMailVisible(bool isVisible)
//****************************************************************************************************************************************************
/// \param[in] scheme the scheme name
//****************************************************************************************************************************************************
void QMLBackend::changeColorScheme(QString const &scheme)
{
void QMLBackend::changeColorScheme(QString const &scheme) {
app().grpc().setColorSchemeName(scheme);
emit colorSchemeNameChanged(this->colorSchemeName());
}
//****************************************************************************************************************************************************
/// \param[in] path The path of the disk cache.
//****************************************************************************************************************************************************
void QMLBackend::setDiskCachePath(QUrl const &path) const
{
void QMLBackend::setDiskCachePath(QUrl const &path) const {
app().grpc().setDiskCachePath(path);
}
@ -332,8 +317,7 @@ void QMLBackend::setDiskCachePath(QUrl const &path) const
//****************************************************************************************************************************************************
/// \return The IMAP port.
//****************************************************************************************************************************************************
int QMLBackend::imapPort() const
{
int QMLBackend::imapPort() const {
return imapPort_;
}
@ -341,10 +325,10 @@ int QMLBackend::imapPort() const
//****************************************************************************************************************************************************
/// \param[in] port The IMAP port.
//****************************************************************************************************************************************************
void QMLBackend::setIMAPPort(int port)
{
if (port == imapPort_)
void QMLBackend::setIMAPPort(int port) {
if (port == imapPort_) {
return;
}
imapPort_ = port;
emit imapPortChanged(port);
}
@ -353,8 +337,7 @@ void QMLBackend::setIMAPPort(int port)
//****************************************************************************************************************************************************
/// \return The SMTP port.
//****************************************************************************************************************************************************
int QMLBackend::smtpPort() const
{
int QMLBackend::smtpPort() const {
return smtpPort_;
}
@ -362,10 +345,10 @@ int QMLBackend::smtpPort() const
//****************************************************************************************************************************************************
/// \param[in] port The SMTP port.
//****************************************************************************************************************************************************
void QMLBackend::setSMTPPort(int port)
{
if (port == smtpPort_)
void QMLBackend::setSMTPPort(int port) {
if (port == smtpPort_) {
return;
}
smtpPort_ = port;
emit smtpPortChanged(port);
}
@ -374,8 +357,7 @@ void QMLBackend::setSMTPPort(int port)
//****************************************************************************************************************************************************
/// \return The value for the 'Use SSL for IMAP' property.
//****************************************************************************************************************************************************
bool QMLBackend::useSSLForIMAP() const
{
bool QMLBackend::useSSLForIMAP() const {
return useSSLForIMAP_;
}
@ -383,10 +365,10 @@ bool QMLBackend::useSSLForIMAP() const
//****************************************************************************************************************************************************
/// \param[in] value The value for the 'Use SSL for IMAP' property.
//****************************************************************************************************************************************************
void QMLBackend::setUseSSLForIMAP(bool value)
{
if (value == useSSLForIMAP_)
void QMLBackend::setUseSSLForIMAP(bool value) {
if (value == useSSLForIMAP_) {
return;
}
useSSLForIMAP_ = value;
emit useSSLForIMAPChanged(value);
}
@ -395,8 +377,7 @@ void QMLBackend::setUseSSLForIMAP(bool value)
//****************************************************************************************************************************************************
/// \return The value for the 'Use SSL for SMTP' property.
//****************************************************************************************************************************************************
bool QMLBackend::useSSLForSMTP() const
{
bool QMLBackend::useSSLForSMTP() const {
return useSSLForSMTP_;
}
@ -404,10 +385,10 @@ bool QMLBackend::useSSLForSMTP() const
//****************************************************************************************************************************************************
/// \param[in] value The value for the 'Use SSL for SMTP' property.
//****************************************************************************************************************************************************
void QMLBackend::setUseSSLForSMTP(bool value)
{
if (value == useSSLForSMTP_)
void QMLBackend::setUseSSLForSMTP(bool value) {
if (value == useSSLForSMTP_) {
return;
}
useSSLForSMTP_ = value;
emit useSSLForSMTPChanged(value);
}
@ -419,8 +400,7 @@ void QMLBackend::setUseSSLForSMTP(bool value)
/// \param[in] useSSLForIMAP The value for the 'Use SSL for IMAP' property
/// \param[in] useSSLForSMTP The value for the 'Use SSL for SMTP' property
//****************************************************************************************************************************************************
void QMLBackend::setMailServerSettings(int imapPort, int smtpPort, bool useSSLForIMAP, bool useSSLForSMTP)
{
void QMLBackend::setMailServerSettings(int imapPort, int smtpPort, bool useSSLForIMAP, bool useSSLForSMTP) {
app().grpc().setMailServerSettings(imapPort, smtpPort, useSSLForIMAP, useSSLForSMTP);
}
@ -429,8 +409,7 @@ void QMLBackend::setMailServerSettings(int imapPort, int smtpPort, bool useSSLFo
/// \param[in] userID the userID.
/// \param[in] wasSignedOut Was the user signed-out.
//****************************************************************************************************************************************************
void QMLBackend::onLoginFinished(QString const &userID, bool wasSignedOut)
{
void QMLBackend::onLoginFinished(QString const &userID, bool wasSignedOut) {
this->retrieveUserList();
qint32 const index = users_->rowOfUserID(userID);
emit loginFinished(index, wasSignedOut);
@ -440,19 +419,18 @@ void QMLBackend::onLoginFinished(QString const &userID, bool wasSignedOut)
//****************************************************************************************************************************************************
/// \param[in] userID the userID.
//****************************************************************************************************************************************************
void QMLBackend::onLoginAlreadyLoggedIn(QString const &userID)
{
void QMLBackend::onLoginAlreadyLoggedIn(QString const &userID) {
this->retrieveUserList();
qint32 const index = users_->rowOfUserID(userID);
emit loginAlreadyLoggedIn(index);
}
//****************************************************************************************************************************************************
/// \param[in] useSSLForIMAP The value for the 'Use SSL for IMAP' property
/// \param[in] useSSLForSMTP The value for the 'Use SSL for SMTP' property
//****************************************************************************************************************************************************
void QMLBackend::onMailServerSettingsChanged(int imapPort, int smtpPort, bool useSSLForIMAP, bool useSSLForSMTP)
{
void QMLBackend::onMailServerSettingsChanged(int imapPort, int smtpPort, bool useSSLForIMAP, bool useSSLForSMTP) {
this->setIMAPPort(imapPort);
this->setSMTPPort(smtpPort);
this->setUseSSLForIMAP(useSSLForIMAP);
@ -463,8 +441,7 @@ void QMLBackend::onMailServerSettingsChanged(int imapPort, int smtpPort, bool us
//****************************************************************************************************************************************************
//
//****************************************************************************************************************************************************
void QMLBackend::onGenericError(ErrorInfo const &info)
{
void QMLBackend::onGenericError(ErrorInfo const &info) {
emit genericError(info.title, info.description);
}
@ -472,38 +449,37 @@ void QMLBackend::onGenericError(ErrorInfo const &info)
//****************************************************************************************************************************************************
/// \param[in] active Should DoH be active.
//****************************************************************************************************************************************************
void QMLBackend::toggleDoH(bool active)
{
if (app().grpc().setIsDoHEnabled(active).ok())
void QMLBackend::toggleDoH(bool active) {
if (app().grpc().setIsDoHEnabled(active).ok()) {
emit isDoHEnabledChanged(active);
}
}
//****************************************************************************************************************************************************
/// \param[in] keychain The new keychain.
//****************************************************************************************************************************************************
void QMLBackend::changeKeychain(QString const &keychain)
{
if (app().grpc().setCurrentKeychain(keychain).ok())
void QMLBackend::changeKeychain(QString const &keychain) {
if (app().grpc().setCurrentKeychain(keychain).ok()) {
emit currentKeychainChanged(keychain);
}
}
//****************************************************************************************************************************************************
/// \param[in] active Should automatic update be turned on.
//****************************************************************************************************************************************************
void QMLBackend::toggleAutomaticUpdate(bool active)
{
if (app().grpc().setIsAutomaticUpdateOn(active).ok())
void QMLBackend::toggleAutomaticUpdate(bool active) {
if (app().grpc().setIsAutomaticUpdateOn(active).ok()) {
emit isAutomaticUpdateOnChanged(active);
}
}
//****************************************************************************************************************************************************
//
//****************************************************************************************************************************************************
void QMLBackend::checkUpdates()
{
void QMLBackend::checkUpdates() {
app().grpc().checkUpdate();
}
@ -511,8 +487,7 @@ void QMLBackend::checkUpdates()
//****************************************************************************************************************************************************
//
//****************************************************************************************************************************************************
void QMLBackend::installUpdate()
{
void QMLBackend::installUpdate() {
app().grpc().installUpdate();
}
@ -520,8 +495,7 @@ void QMLBackend::installUpdate()
//****************************************************************************************************************************************************
//
//****************************************************************************************************************************************************
void QMLBackend::triggerReset()
{
void QMLBackend::triggerReset() {
app().grpc().triggerReset();
}
@ -529,8 +503,7 @@ void QMLBackend::triggerReset()
//****************************************************************************************************************************************************
//
//****************************************************************************************************************************************************
void QMLBackend::onResetFinished()
{
void QMLBackend::onResetFinished() {
emit resetFinished();
this->restart();
}
@ -539,8 +512,7 @@ void QMLBackend::onResetFinished()
//****************************************************************************************************************************************************
// onVersionChanged update dynamic link related to version
//****************************************************************************************************************************************************
void QMLBackend::onVersionChanged()
{
void QMLBackend::onVersionChanged() {
emit releaseNotesLinkChanged(releaseNotesLink());
emit landingPageLinkChanged(landingPageLink());
}
@ -549,10 +521,10 @@ void QMLBackend::onVersionChanged()
//****************************************************************************************************************************************************
//
//****************************************************************************************************************************************************
void QMLBackend::exportTLSCertificates()
{
void QMLBackend::exportTLSCertificates() {
QString const folderPath = QFileDialog::getExistingDirectory(nullptr, QObject::tr("Select directory"),
QStandardPaths::writableLocation(QStandardPaths::HomeLocation));
if (!folderPath.isEmpty())
if (!folderPath.isEmpty()) {
app().grpc().exportTLSCertificates(folderPath);
}
}

View File

@ -31,8 +31,7 @@
//****************************************************************************************************************************************************
/// \brief Bridge C++ backend class.
//****************************************************************************************************************************************************
class QMLBackend: public QObject
{
class QMLBackend : public QObject {
Q_OBJECT
public: // member functions.
@ -79,28 +78,109 @@ public: // Qt/QML properties. Note that the NOTIFY-er signal is required even fo
Q_PROPERTY(QString currentEmailClient READ currentEmailClient NOTIFY currentEmailClientChanged)
Q_PROPERTY(QStringList availableKeychain READ availableKeychain NOTIFY availableKeychainChanged)
Q_PROPERTY(QString currentKeychain READ currentKeychain NOTIFY currentKeychainChanged)
Q_PROPERTY(UserList* users MEMBER users_ NOTIFY usersChanged)
Q_PROPERTY(UserList *users MEMBER users_ NOTIFY usersChanged)
Q_PROPERTY(bool dockIconVisible READ dockIconVisible WRITE setDockIconVisible NOTIFY dockIconVisibleChanged)
// Qt Property system setters & getters.
bool showOnStartup() const { bool v = false; app().grpc().showOnStartup(v); return v; };
bool showOnStartup() const {
bool v = false;
app().grpc().showOnStartup(v);
return v;
};
bool showSplashScreen() const { return showSplashScreen_; };
void setShowSplashScreen(bool show) { if (show != showSplashScreen_) { showSplashScreen_ = show; emit showSplashScreenChanged(show); } }
void setShowSplashScreen(bool show) { if (show != showSplashScreen_) { showSplashScreen_ = show; emit showSplashScreenChanged(show); }}
QString goos() { return goos_; }
QUrl logsPath() const { return logsPath_; }
QUrl licensePath() const { return licensePath_; }
QUrl releaseNotesLink() const { QUrl link; app().grpc().releaseNotesPageLink(link); return link; }
QUrl dependencyLicensesLink() const { QUrl link; app().grpc().dependencyLicensesLink(link); return link; }
QUrl landingPageLink() const { QUrl link; app().grpc().landingPageLink(link); return link; }
QUrl releaseNotesLink() const {
QUrl link;
app().grpc().releaseNotesPageLink(link);
return link;
}
QUrl dependencyLicensesLink() const {
QUrl link;
app().grpc().dependencyLicensesLink(link);
return link;
}
QUrl landingPageLink() const {
QUrl link;
app().grpc().landingPageLink(link);
return link;
}
QString appname() const { return QString(PROJECT_FULL_NAME); }
QString vendor() const { return QString(PROJECT_VENDOR); }
QString version() const { QString version; app().grpc().version(version); return version; }
QString hostname() const { QString hostname; app().grpc().hostname(hostname); return hostname; }
bool isAutostartOn() const { bool v; app().grpc().isAutostartOn(v); return v; };
bool isBetaEnabled() const { bool v; app().grpc().isBetaEnabled(v); return v; }
bool isAllMailVisible() const { bool v; app().grpc().isAllMailVisible(v); return v; }
QString colorSchemeName() const { QString name; app().grpc().colorSchemeName(name); return name; }
QUrl diskCachePath() const { QUrl path; app().grpc().diskCachePath(path); return path; }
QString version() const {
QString version;
app().grpc().version(version);
return version;
}
QString hostname() const {
QString hostname;
app().grpc().hostname(hostname);
return hostname;
}
bool isAutostartOn() const {
bool v;
app().grpc().isAutostartOn(v);
return v;
};
bool isBetaEnabled() const {
bool v;
app().grpc().isBetaEnabled(v);
return v;
}
bool isAllMailVisible() const {
bool v;
app().grpc().isAllMailVisible(v);
return v;
}
QString colorSchemeName() const {
QString name;
app().grpc().colorSchemeName(name);
return name;
}
QUrl diskCachePath() const {
QUrl path;
app().grpc().diskCachePath(path);
return path;
}
bool useSSLForIMAP() const;
void setUseSSLForIMAP(bool value);
bool useSSLForSMTP() const;
@ -109,15 +189,56 @@ public: // Qt/QML properties. Note that the NOTIFY-er signal is required even fo
void setIMAPPort(int port);
int smtpPort() const;
void setSMTPPort(int port);
bool isDoHEnabled() const { bool isEnabled; app().grpc().isDoHEnabled(isEnabled); return isEnabled;}
bool isFirstGUIStart() const { bool v; app().grpc().isFirstGUIStart(v); return v; };
bool isAutomaticUpdateOn() const { bool isOn = false; app().grpc().isAutomaticUpdateOn(isOn); return isOn; }
QString currentEmailClient() { QString client; app().grpc().currentEmailClient(client); return client;}
QStringList availableKeychain() const { QStringList keychains; app().grpc().availableKeychains(keychains); return keychains; }
QString currentKeychain() const { QString keychain; app().grpc().currentKeychain(keychain); return keychain; }
bool isDoHEnabled() const {
bool isEnabled;
app().grpc().isDoHEnabled(isEnabled);
return isEnabled;
}
bool isFirstGUIStart() const {
bool v;
app().grpc().isFirstGUIStart(v);
return v;
};
bool isAutomaticUpdateOn() const {
bool isOn = false;
app().grpc().isAutomaticUpdateOn(isOn);
return isOn;
}
QString currentEmailClient() {
QString client;
app().grpc().currentEmailClient(client);
return client;
}
QStringList availableKeychain() const {
QStringList keychains;
app().grpc().availableKeychains(keychains);
return keychains;
}
QString currentKeychain() const {
QString keychain;
app().grpc().currentKeychain(keychain);
return keychain;
}
bool dockIconVisible() const { return getDockIconVisibleState(); };
void setDockIconVisible(bool visible) { setDockIconVisibleState(visible); emit dockIconVisibleChanged(visible); }
signals: // Signal used by the Qt property system. Many of them are unused but required to avoid warning from the QML engine.
void showSplashScreenChanged(bool value);
void showOnStartupChanged(bool value);
@ -145,7 +266,7 @@ signals: // Signal used by the Qt property system. Many of them are unused but r
void availableKeychainChanged(QStringList const &keychains);
void hostnameChanged(QString const &hostname);
void isAutostartOnChanged(bool value);
void usersChanged(UserList* users);
void usersChanged(UserList *users);
void dockIconVisibleChanged(bool value);
public slots: // slot for signals received from QML -> To be forwarded to Bridge via RPC Client calls.
@ -153,14 +274,28 @@ public slots: // slot for signals received from QML -> To be forwarded to Bridge
void toggleBeta(bool active);
void changeIsAllMailVisible(bool isVisible);
void changeColorScheme(QString const &scheme);
void setDiskCachePath(QUrl const& path) const;
void login(QString const& username, QString const& password) { app().grpc().login(username, password);}
void login2FA(QString const& username, QString const& code) { app().grpc().login2FA(username, code);}
void login2Password(QString const& username, QString const& password) { app().grpc().login2Passwords(username, password);}
void loginAbort(QString const& username){ app().grpc().loginAbort(username);}
void setDiskCachePath(QUrl const &path) const;
void login(QString const &username, QString const &password) { app().grpc().login(username, password); }
void login2FA(QString const &username, QString const &code) { app().grpc().login2FA(username, code); }
void login2Password(QString const &username, QString const &password) { app().grpc().login2Passwords(username, password); }
void loginAbort(QString const &username) { app().grpc().loginAbort(username); }
void toggleDoH(bool active);
void toggleAutomaticUpdate(bool makeItActive);
void updateCurrentMailClient() { emit currentEmailClientChanged(currentEmailClient()); }
void changeKeychain(QString const &keychain);
void guiReady();
void quit();
@ -169,8 +304,13 @@ public slots: // slot for signals received from QML -> To be forwarded to Bridge
void checkUpdates();
void installUpdate();
void triggerReset();
void reportBug(QString const &description, QString const& address, QString const &emailClient, bool includeLogs) {
app().grpc().reportBug(description, address, emailClient, includeLogs); }
void reportBug(QString const &description, QString const &address, QString const &emailClient, bool includeLogs) {
app().grpc().reportBug(description, address, emailClient, includeLogs);
}
void exportTLSCertificates();
void onResetFinished();
void onVersionChanged();
@ -178,7 +318,7 @@ public slots: // slot for signals received from QML -> To be forwarded to Bridge
public slots: // slot for signals received from gRPC that need transformation instead of simple forwarding
void onMailServerSettingsChanged(int imapPort, int smtpPort, bool useSSLForIMAP, bool useSSLForSMTP); ///< Slot for the ConnectionModeChanged gRPC event.
void onGenericError(bridgepp::ErrorInfo const& info); ///< Slot for generic errors received from the gRPC service.
void onGenericError(bridgepp::ErrorInfo const &info); ///< Slot for generic errors received from the gRPC service.
void onLoginFinished(QString const &userID, bool wasSignedOut); ///< Slot for LoginFinished gRPC event.
void onLoginAlreadyLoggedIn(QString const &userID); ///< Slot for the LoginAlreadyLoggedIn gRPC event.
@ -192,17 +332,17 @@ signals: // Signals received from the Go backend, to be forwarded to QML
void loginFreeUserError();
void loginConnectionError(QString const &errorMsg);
void login2FARequested(QString const &username);
void login2FAError(QString const& errorMsg);
void login2FAErrorAbort(QString const& errorMsg);
void login2FAError(QString const &errorMsg);
void login2FAErrorAbort(QString const &errorMsg);
void login2PasswordRequested();
void login2PasswordError(QString const& errorMsg);
void login2PasswordErrorAbort(QString const& errorMsg);
void login2PasswordError(QString const &errorMsg);
void login2PasswordErrorAbort(QString const &errorMsg);
void loginFinished(int index, bool wasSignedOut);
void loginAlreadyLoggedIn(int index);
void updateManualReady(QString const& version);
void updateManualReady(QString const &version);
void updateManualRestartNeeded();
void updateManualError();
void updateForce(QString const& version);
void updateForce(QString const &version);
void updateForceError();
void updateSilentRestartNeeded();
void updateSilentError();
@ -218,11 +358,11 @@ signals: // Signals received from the Go backend, to be forwarded to QML
void changeKeychainFinished();
void notifyHasNoKeychain();
void notifyRebuildKeychain();
void noActiveKeyForRecipient(QString const& email);
void addressChanged(QString const& address);
void addressChangedLogout(QString const& address);
void noActiveKeyForRecipient(QString const &email);
void addressChanged(QString const &address);
void addressChangedLogout(QString const &address);
void apiCertIssue();
void userDisconnected(QString const& username);
void userDisconnected(QString const &username);
void internetOff();
void internetOn();
void resetFinished();
@ -231,14 +371,14 @@ signals: // Signals received from the Go backend, to be forwarded to QML
void bugReportSendError();
void showMainWindow();
void hideMainWindow();
void genericError(QString const& title, QString const& description);
void genericError(QString const &title, QString const &description);
private: // member functions
void retrieveUserList(); ///< Retrieve the list of users via gRPC.
void connectGrpcEvents(); ///< Connect gRPC that need to be forwarded to QML via backend signals
private: // data members
UserList* users_ { nullptr }; ///< The user list. Owned by backend.
UserList *users_ { nullptr }; ///< The user list. Owned by backend.
std::unique_ptr<bridgepp::Overseer> eventStreamOverseer_; ///< The event stream overseer.
bool showSplashScreen_ { false }; ///< The cached version of show splash screen. Retrieved on startup from bridge, and potentially modified locally.
QString goos_; ///< The cached version of the GOOS variable.

View File

@ -17,14 +17,17 @@
#include "SentryUtils.h"
static constexpr const char* LoggerName = "bridge-gui";
void reportSentryEvent(sentry_level_t level, const char* message) {
static constexpr const char *LoggerName = "bridge-gui";
void reportSentryEvent(sentry_level_t level, const char *message) {
auto event = sentry_value_new_message_event(level, LoggerName, message);
sentry_capture_event(event);
}
void reportSentryException(sentry_level_t level, const char* message, const char* exceptionType, const char* exception) {
void reportSentryException(sentry_level_t level, const char *message, const char *exceptionType, const char *exception) {
auto event = sentry_value_new_message_event(level, LoggerName, message);
sentry_event_add_exception(event, sentry_value_new_exception(exceptionType, exception));
sentry_capture_event(event);

View File

@ -18,9 +18,11 @@
#ifndef BRIDGE_GUI_SENTRYUTILS_H
#define BRIDGE_GUI_SENTRYUTILS_H
#include <sentry.h>
void reportSentryEvent(sentry_level_t level, const char* message);
void reportSentryException(sentry_level_t level, const char* message, const char* exceptionType, const char* exception);
void reportSentryEvent(sentry_level_t level, const char *message);
void reportSentryException(sentry_level_t level, const char *message, const char *exceptionType, const char *exception);
#endif //BRIDGE_GUI_SENTRYUTILS_H

View File

@ -26,8 +26,7 @@ using namespace bridgepp;
/// \param[in] parent The parent object of the user list.
//****************************************************************************************************************************************************
UserList::UserList(QObject *parent)
: QAbstractListModel(parent)
{
: QAbstractListModel(parent) {
/// \todo use mutex to prevent concurrent access
}
@ -35,9 +34,8 @@ UserList::UserList(QObject *parent)
//****************************************************************************************************************************************************
//
//****************************************************************************************************************************************************
void UserList::connectGRPCEvents() const
{
GRPCClient& client = app().grpc();
void UserList::connectGRPCEvents() const {
GRPCClient &client = app().grpc();
connect(&client, &GRPCClient::userChanged, this, &UserList::onUserChanged);
connect(&client, &GRPCClient::toggleSplitModeFinished, this, &UserList::onToggleSplitModeFinished);
}
@ -46,8 +44,7 @@ void UserList::connectGRPCEvents() const
//****************************************************************************************************************************************************
//
//****************************************************************************************************************************************************
int UserList::rowCount(QModelIndex const &) const
{
int UserList::rowCount(QModelIndex const &) const {
return users_.size();
}
@ -57,14 +54,14 @@ int UserList::rowCount(QModelIndex const &) const
/// \param[in] role The role to retrieve data for.
/// \return The data at the index for the given role.
//****************************************************************************************************************************************************
QVariant UserList::data(QModelIndex const &index, int role) const
{
QVariant UserList::data(QModelIndex const &index, int role) const {
/// This It does not seem to be used, but the method is required by the base class.
/// From the original QtThe recipe QML backend User model, the User is always returned, regardless of the role.
Q_UNUSED(role)
int const row = index.row();
if ((row < 0) || (row >= users_.size()))
if ((row < 0) || (row >= users_.size())) {
return QVariant();
}
return QVariant::fromValue(users_[row].get());
}
@ -74,11 +71,12 @@ QVariant UserList::data(QModelIndex const &index, int role) const
/// \return the row of the user.
/// \return -1 if the userID is not in the list
//****************************************************************************************************************************************************
int UserList::rowOfUserID(QString const &userID) const
{
for (qint32 row = 0; row < users_.count(); ++row)
if (userID == users_[row]->property("id"))
int UserList::rowOfUserID(QString const &userID) const {
for (qint32 row = 0; row < users_.count(); ++row) {
if (userID == users_[row]->property("id")) {
return row;
}
}
return -1;
}
@ -86,8 +84,7 @@ int UserList::rowOfUserID(QString const &userID) const
//****************************************************************************************************************************************************
/// \param[in] users The new user list.
//****************************************************************************************************************************************************
void UserList::reset(QList<SPUser> const &users)
{
void UserList::reset(QList<SPUser> const &users) {
this->beginResetModel();
users_ = users;
this->endResetModel();
@ -98,8 +95,7 @@ void UserList::reset(QList<SPUser> const &users)
//****************************************************************************************************************************************************
/// \param[in] user The user.
//****************************************************************************************************************************************************
void UserList::appendUser(SPUser const &user)
{
void UserList::appendUser(SPUser const &user) {
int const size = users_.size();
this->beginInsertRows(QModelIndex(), size, size);
users_.append(user);
@ -111,10 +107,10 @@ void UserList::appendUser(SPUser const &user)
//****************************************************************************************************************************************************
/// \param[in] row The row.
//****************************************************************************************************************************************************
void UserList::removeUserAt(int row)
{
if ((row < 0) && (row >= users_.size()))
void UserList::removeUserAt(int row) {
if ((row < 0) && (row >= users_.size())) {
return;
}
this->beginRemoveRows(QModelIndex(), row, row);
users_.removeAt(row);
this->endRemoveRows();
@ -126,10 +122,8 @@ void UserList::removeUserAt(int row)
/// \param[in] row The row.
/// \param[in] user The user.
//****************************************************************************************************************************************************
void UserList::updateUserAtRow(int row, User const &user)
{
if ((row < 0) || (row >= users_.count()))
{
void UserList::updateUserAtRow(int row, User const &user) {
if ((row < 0) || (row >= users_.count())) {
app().log().error(QString("invalid user at row %2 (user userCount = %2)").arg(row).arg(users_.count()));
return;
}
@ -146,10 +140,10 @@ void UserList::updateUserAtRow(int row, User const &user)
/// \return The user with the given ID.
/// \return A null pointer if the user could not be found.
//****************************************************************************************************************************************************
bridgepp::SPUser UserList::getUserWithID(QString const &userID) const
{
QList<SPUser>::const_iterator it = std::find_if(users_.begin(), users_.end(), [userID](SPUser const & user) -> bool {
return user && user->id() == userID; });
bridgepp::SPUser UserList::getUserWithID(QString const &userID) const {
QList<SPUser>::const_iterator it = std::find_if(users_.begin(), users_.end(), [userID](SPUser const &user) -> bool {
return user && user->id() == userID;
});
return (it == users_.end()) ? nullptr : *it;
}
@ -157,10 +151,10 @@ bridgepp::SPUser UserList::getUserWithID(QString const &userID) const
//****************************************************************************************************************************************************
/// \param[in] row The row.
//****************************************************************************************************************************************************
User *UserList::get(int row) const
{
if ((row < 0) || (row >= users_.count()))
User *UserList::get(int row) const {
if ((row < 0) || (row >= users_.count())) {
return nullptr;
}
app().log().trace(QString("Retrieving user at row %1 (user userCount = %2)").arg(row).arg(users_.count()));
return users_[row].get();
@ -170,25 +164,21 @@ User *UserList::get(int row) const
//****************************************************************************************************************************************************
/// \param[in] userID The userID.
//****************************************************************************************************************************************************
void UserList::onUserChanged(QString const &userID)
{
void UserList::onUserChanged(QString const &userID) {
int const index = this->rowOfUserID(userID);
SPUser user;
grpc::Status status = app().grpc().getUser(userID, user);
QQmlEngine::setObjectOwnership(user.get(), QQmlEngine::CppOwnership);
if ((!user) || (!status.ok()))
{
if (index >= 0) // user exists here but not in the go backend. we delete it.
{
if ((!user) || (!status.ok())) {
if (index >= 0) { // user exists here but not in the go backend. we delete it.
app().log().trace(QString("Removing user from user list: %1").arg(userID));
this->removeUserAt(index);
}
return;
}
if (index < 0)
{
if (index < 0) {
app().log().trace(QString("Adding user in user list: %1").arg(userID));
this->appendUser(user);
return;
@ -205,11 +195,9 @@ void UserList::onUserChanged(QString const &userID)
///
/// \param[in] userID the userID.
//****************************************************************************************************************************************************
void UserList::onToggleSplitModeFinished(QString const &userID)
{
void UserList::onToggleSplitModeFinished(QString const &userID) {
int const index = this->rowOfUserID(userID);
if (index < 0)
{
if (index < 0) {
app().log().error(QString("Received toggleSplitModeFinished event for unknown userID %1").arg(userID));
return;
}
@ -221,7 +209,6 @@ void UserList::onToggleSplitModeFinished(QString const &userID)
//****************************************************************************************************************************************************
/// \return THe number of items in the list.
//****************************************************************************************************************************************************
int UserList::count() const
{
int UserList::count() const {
return users_.size();
}

View File

@ -28,8 +28,7 @@
//****************************************************************************************************************************************************
/// \brief User list class.
//****************************************************************************************************************************************************
class UserList : public QAbstractListModel
{
class UserList : public QAbstractListModel {
Q_OBJECT
public: // member functions.
UserList(QObject *parent); ///< Default constructor.
@ -44,7 +43,7 @@ public: // member functions.
void removeUserAt(int row); ///< Remove the user at a given row
void appendUser(bridgepp::SPUser const &user); ///< Add a new user.
void updateUserAtRow(int row, bridgepp::User const &user); ///< Update the user at given row.
bridgepp::SPUser getUserWithID(QString const& userID) const; ///< Retrieve the user with the given ID.
bridgepp::SPUser getUserWithID(QString const &userID) const; ///< Retrieve the user with the given ID.
// the userCount property.
Q_PROPERTY(int count READ count NOTIFY countChanged)

View File

@ -30,18 +30,16 @@
#include <project_sentry_config.h>
using namespace bridgepp;
namespace
{
namespace {
/// \brief The file extension for the bridge executable file.
#ifdef Q_OS_WIN32
QString const exeSuffix = ".exe";
QString const exeSuffix = ".exe";
#else
QString const exeSuffix;
QString const exeSuffix;
#endif
QString const bridgeLock = "bridge-v3-gui.lock"; ///< file name used for the lock file.
@ -56,20 +54,20 @@ qint64 const grpcServiceConfigWaitDelayMs = 180000; ///< The wait delay for the
/// \return The path of the bridge executable.
/// \return A null string if the executable could not be located.
//****************************************************************************************************************************************************
QString locateBridgeExe()
{
QString locateBridgeExe() {
QFileInfo const fileInfo(QDir(QCoreApplication::applicationDirPath()).absoluteFilePath(exeName));
return (fileInfo.exists() && fileInfo.isFile() && fileInfo.isExecutable()) ? fileInfo.absoluteFilePath() : QString();
return (fileInfo.exists() && fileInfo.isFile() && fileInfo.isExecutable()) ? fileInfo.absoluteFilePath() : QString();
}
//****************************************************************************************************************************************************
/// // initialize the Qt application.
//****************************************************************************************************************************************************
void initQtApplication()
{
void initQtApplication() {
QString const qsgInfo = QProcessEnvironment::systemEnvironment().value("QSG_INFO");
if ((!qsgInfo.isEmpty()) && (qsgInfo != "0"))
if ((!qsgInfo.isEmpty()) && (qsgInfo != "0")) {
QLoggingCategory::setFilterRules("qt.scenegraph.general=true");
}
QGuiApplication::setApplicationName(PROJECT_FULL_NAME);
QGuiApplication::setApplicationVersion(PROJECT_VER);
@ -92,28 +90,30 @@ void initQtApplication()
//****************************************************************************************************************************************************
/// \return A reference to the log.
//****************************************************************************************************************************************************
Log &initLog()
{
Log &initLog() {
Log &log = app().log();
log.registerAsQtMessageHandler();
log.setEchoInConsole(true);
// remove old gui log files
QDir const logsDir(userLogsDir());
for (QFileInfo const fileInfo: logsDir.entryInfoList({ "gui_v*.log" }, QDir::Filter::Files)) // entryInfolist apparently only support wildcards, not regex.
for (QFileInfo const fileInfo: logsDir.entryInfoList({ "gui_v*.log" }, QDir::Filter::Files)) { // entryInfolist apparently only support wildcards, not regex.
QFile(fileInfo.absoluteFilePath()).remove();
}
// create new GUI log file
QString error;
if (!log.startWritingToFile(logsDir.absoluteFilePath(QString("gui_v%1_%2.log").arg(PROJECT_VER).arg(QDateTime::currentSecsSinceEpoch())), &error))
if (!log.startWritingToFile(logsDir.absoluteFilePath(QString("gui_v%1_%2.log").arg(PROJECT_VER).arg(QDateTime::currentSecsSinceEpoch())), &error)) {
log.error(error);
}
log.info("bridge-gui starting");
QString const qtCompileTimeVersion = QT_VERSION_STR;
QString const qtRuntimeVersion = qVersion();
QString msg = QString("Using Qt %1").arg(qtRuntimeVersion);
if (qtRuntimeVersion != qtCompileTimeVersion)
if (qtRuntimeVersion != qtCompileTimeVersion) {
msg += QString(" (compiled against %1)").arg(qtCompileTimeVersion);
}
log.info(msg);
return log;
@ -123,8 +123,7 @@ Log &initLog()
//****************************************************************************************************************************************************
/// \param[in] engine The QML component.
//****************************************************************************************************************************************************
QQmlComponent *createRootQmlComponent(QQmlApplicationEngine &engine)
{
QQmlComponent *createRootQmlComponent(QQmlApplicationEngine &engine) {
QString const qrcQmlDir = "qrc:/qml";
qmlRegisterSingletonInstance("Proton", 1, 0, "Backend", &app().backend());
qmlRegisterType<UserList>("Proton", 1, 0, "UserList");
@ -138,8 +137,7 @@ QQmlComponent *createRootQmlComponent(QQmlApplicationEngine &engine)
QQuickStyle::setStyle("Proton");
rootComponent->loadUrl(QUrl(qrcQmlDir + "/Bridge.qml"));
if (rootComponent->status() != QQmlComponent::Status::Ready)
{
if (rootComponent->status() != QQmlComponent::Status::Ready) {
app().log().error(rootComponent->errorString());
throw Exception("Could not load QML component");
}
@ -151,21 +149,18 @@ QQmlComponent *createRootQmlComponent(QQmlApplicationEngine &engine)
/// \param[in] lock The lock file to be checked.
/// \return True if the lock can be taken, false otherwise.
//****************************************************************************************************************************************************
bool checkSingleInstance(QLockFile &lock)
{
bool checkSingleInstance(QLockFile &lock) {
lock.setStaleLockTime(0);
if (!lock.tryLock())
{
if (!lock.tryLock()) {
qint64 pid;
QString hostname, appName, details;
if (lock.getLockInfo(&pid, &hostname, &appName))
if (lock.getLockInfo(&pid, &hostname, &appName)) {
details = QString("(PID : %1 - Host : %2 - App : %3)").arg(pid).arg(hostname, appName);
}
app().log().error(QString("Instance already exists %1 %2").arg(lock.fileName(), details));
return false;
}
else
{
} else {
app().log().info(QString("lock file created %1").arg(lock.fileName()));
}
return true;
@ -175,8 +170,7 @@ bool checkSingleInstance(QLockFile &lock)
//****************************************************************************************************************************************************
/// \return QUrl to reach the bridge API.
//****************************************************************************************************************************************************
QUrl getApiUrl()
{
QUrl getApiUrl() {
QUrl url;
// use default url.
url.setScheme("http");
@ -185,17 +179,17 @@ QUrl getApiUrl()
// override with what can be found in the prefs.json file.
QFile prefFile(QString("%1/%2").arg(bridgepp::userConfigDir(), "prefs.json"));
if (prefFile.exists())
{
prefFile.open(QIODevice::ReadOnly|QIODevice::Text);
if (prefFile.exists()) {
prefFile.open(QIODevice::ReadOnly | QIODevice::Text);
QByteArray data = prefFile.readAll();
prefFile.close();
QJsonDocument doc = QJsonDocument::fromJson(data);
if (!doc.isNull()) {
QString userPortApi = "user_port_api";
QJsonObject obj = doc.object();
if (!obj.isEmpty() && obj.contains(userPortApi))
if (!obj.isEmpty() && obj.contains(userPortApi)) {
url.setPort(doc.object()[userPortApi].toString().toInt());
}
}
}
return url;
@ -205,8 +199,7 @@ QUrl getApiUrl()
//****************************************************************************************************************************************************
/// \return The URL for the focus endpoint of the bridge API URL.
//****************************************************************************************************************************************************
QUrl getFocusUrl()
{
QUrl getFocusUrl() {
QUrl url = getApiUrl();
url.setPath("/focus");
return url;
@ -216,8 +209,7 @@ QUrl getFocusUrl()
//****************************************************************************************************************************************************
/// \return true if an instance of bridge is already running.
//****************************************************************************************************************************************************
bool isBridgeRunning()
{
bool isBridgeRunning() {
FocusGRPCClient client;
return client.connectToServer(500); // we time out after 1 second and consider no other instance is running;
}
@ -226,19 +218,18 @@ bool isBridgeRunning()
//****************************************************************************************************************************************************
/// \brief Use api to bring focus on existing bridge instance.
//****************************************************************************************************************************************************
void focusOtherInstance()
{
try
{
void focusOtherInstance() {
try {
FocusGRPCClient client;
QString error;
if (!client.connectToServer(5000, &error))
if (!client.connectToServer(5000, &error)) {
throw Exception(QString("Could not connect to bridge focus service for a raise call: %1").arg(error));
if (!client.raise().ok())
}
if (!client.raise().ok()) {
throw Exception(QString("The raise call to the bridge focus service failed."));
}
}
catch (Exception const& e)
{
catch (Exception const &e) {
app().log().error(e.qwhat());
reportSentryException(SENTRY_LEVEL_ERROR, "Exception occurred during focusOtherInstance()", "Exception", e.what());
}
@ -248,22 +239,22 @@ void focusOtherInstance()
//****************************************************************************************************************************************************
/// \param [in] args list of arguments to pass to bridge.
//****************************************************************************************************************************************************
void launchBridge(QStringList const &args)
{
UPOverseer& overseer = app().bridgeOverseer();
void launchBridge(QStringList const &args) {
UPOverseer &overseer = app().bridgeOverseer();
overseer.reset();
const QString bridgeExePath = locateBridgeExe();
if (bridgeExePath.isEmpty())
if (bridgeExePath.isEmpty()) {
throw Exception("Could not locate the bridge executable path");
else
} else {
app().log().debug(QString("Bridge executable path: %1").arg(QDir::toNativeSeparators(bridgeExePath)));
}
qint64 const pid = qApp->applicationPid();
QStringList const params = QStringList { "--grpc", "--parent-pid", QString::number(pid) } + args ;
QStringList const params = QStringList { "--grpc", "--parent-pid", QString::number(pid) } + args;
app().log().info(QString("Launching bridge process with command \"%1\" %2").arg(bridgeExePath, params.join(" ")));
overseer = std::make_unique<Overseer>(new ProcessMonitor(bridgeExePath, params , nullptr), nullptr);
overseer = std::make_unique<Overseer>(new ProcessMonitor(bridgeExePath, params, nullptr), nullptr);
overseer->startWorker(true);
}
@ -271,16 +262,15 @@ void launchBridge(QStringList const &args)
//****************************************************************************************************************************************************
//
//****************************************************************************************************************************************************
void closeBridgeApp()
{
void closeBridgeApp() {
app().grpc().quit(); // this will cause the grpc service and the bridge app to close.
UPOverseer& overseer = app().bridgeOverseer();
if (!overseer) // The app was run in 'attach' mode and attached to an existing instance of Bridge. We're not monitoring it.
UPOverseer &overseer = app().bridgeOverseer();
if (!overseer) { // The app was run in 'attach' mode and attached to an existing instance of Bridge. We're not monitoring it.
return;
}
while (!overseer->isFinished())
{
while (!overseer->isFinished()) {
QThread::msleep(20);
}
}
@ -291,10 +281,9 @@ void closeBridgeApp()
/// \param[in] argv The list of command-line arguments.
/// \return The exit code for the application.
//****************************************************************************************************************************************************
int main(int argc, char *argv[])
{
int main(int argc, char *argv[]) {
// Init sentry.
sentry_options_t* sentryOptions = sentry_options_new();
sentry_options_t *sentryOptions = sentry_options_new();
sentry_options_set_dsn(sentryOptions, SentryDNS);
{
const QString sentryCachePath = sentryCacheDir();
@ -307,24 +296,23 @@ int main(int argc, char *argv[])
std::cerr << "Failed to initialize sentry" << std::endl;
}
auto sentryClose = qScopeGuard([]{sentry_close();});
auto sentryClose = qScopeGuard([] { sentry_close(); });
// The application instance is needed to display system message boxes. As we may have to do it in the exception handler,
// application instance is create outside the try/catch clause.
if (QSysInfo::productType() != "windows")
if (QSysInfo::productType() != "windows") {
QCoreApplication::setAttribute(Qt::AA_UseSoftwareOpenGL);
}
QApplication guiApp(argc, argv);
try
{
try {
initQtApplication();
Log &log = initLog();
QLockFile lock(bridgepp::userCacheDir() + "/" + bridgeLock);
if (!checkSingleInstance(lock))
{
if (!checkSingleInstance(lock)) {
focusOtherInstance();
return EXIT_FAILURE;
}
@ -340,10 +328,10 @@ int main(int argc, char *argv[])
// these outputs and output them on the command-line.
log.setLevel(cliOptions.logLevel);
if (!cliOptions.attach)
{
if (isBridgeRunning())
if (!cliOptions.attach) {
if (isBridgeRunning()) {
throw Exception("An orphan instance of bridge is already running. Please terminate it and relaunch the application.");
}
// before launching bridge, we remove any trailing service config file, because we need to make sure we get a newly generated one.
GRPCClient::removeServiceConfigFile();
@ -352,8 +340,9 @@ int main(int argc, char *argv[])
log.info(QString("Retrieving gRPC service configuration from '%1'").arg(QDir::toNativeSeparators(grpcServerConfigPath())));
app().backend().init(GRPCClient::waitAndRetrieveServiceConfig(cliOptions.attach ? 0 : grpcServiceConfigWaitDelayMs, app().bridgeMonitor()));
if (!cliOptions.attach)
if (!cliOptions.attach) {
GRPCClient::removeServiceConfigFile();
}
// gRPC communication is established. From now on, log events will be sent to bridge via gRPC. bridge will write these to file,
// and will output then on console if appropriate. If we are not running in attached mode we intercept bridge stdout & stderr and
@ -370,19 +359,18 @@ int main(int argc, char *argv[])
QQmlApplicationEngine engine;
std::unique_ptr<QQmlComponent> rootComponent(createRootQmlComponent(engine));
std::unique_ptr<QObject>rootObject(rootComponent->create(engine.rootContext()));
if (!rootObject)
std::unique_ptr<QObject> rootObject(rootComponent->create(engine.rootContext()));
if (!rootObject) {
throw Exception("Could not create root object.");
}
ProcessMonitor *bridgeMonitor = app().bridgeMonitor();
bool bridgeExited = false;
bool startError = false;
QMetaObject::Connection connection;
if (bridgeMonitor)
{
const ProcessMonitor::MonitorStatus& status = bridgeMonitor->getStatus();
if (status.ended && !cliOptions.attach)
{
if (bridgeMonitor) {
const ProcessMonitor::MonitorStatus &status = bridgeMonitor->getStatus();
if (status.ended && !cliOptions.attach) {
// ProcessMonitor already stopped meaning we are attached to an orphan Bridge.
// Restart the full process to be sure there is no more bridge orphans
app().log().error("Found orphan bridge, need to restart.");
@ -390,21 +378,18 @@ int main(int argc, char *argv[])
app().backend().restart();
bridgeExited = true;
startError = true;
}
else
{
} else {
app().log().debug(QString("Monitoring Bridge PID : %1").arg(status.pid));
connection = QObject::connect(bridgeMonitor, &ProcessMonitor::processExited, [&](int returnCode) {
bridgeExited = true;// clazy:exclude=lambda-in-connect
qGuiApp->exit(returnCode);
});
bridgeExited = true;// clazy:exclude=lambda-in-connect
qGuiApp->exit(returnCode);
});
}
}
int result = 0;
if (!startError)
{
if (!startError) {
// we succeeded in launching bridge, so we can be set as mainExecutable.
app().grpc().setMainExecutable(QString::fromLocal8Bit(argv[0]));
result = QGuiApplication::exec();
@ -412,21 +397,22 @@ int main(int argc, char *argv[])
QObject::disconnect(connection);
app().grpc().stopEventStreamReader();
if (!app().backend().waitForEventStreamReaderToFinish(5000))
if (!app().backend().waitForEventStreamReaderToFinish(5000)) {
log.warn("Event stream reader took too long to finish.");
}
// We manually delete the QML components to avoid warnings error due to order of deletion of C++ / JS objects and singletons.
rootObject.reset();
rootComponent.reset();
if (!bridgeExited)
if (!bridgeExited) {
closeBridgeApp();
}
// release the lock file
lock.unlock();
return result;
}
catch (Exception const &e)
{
catch (Exception const &e) {
reportSentryException(SENTRY_LEVEL_ERROR, "Exception occurred during main", "Exception", e.what());
QMessageBox::critical(nullptr, "Error", e.qwhat());
QTextStream(stderr) << e.qwhat() << "\n";

View File

@ -21,8 +21,7 @@
#include <random>
namespace bridgepp
{
namespace bridgepp {
namespace {
@ -56,8 +55,7 @@ QStringList const lastNames {
//****************************************************************************************************************************************************
/// \brief Return the 64 bit Mersenne twister random number generator.
//****************************************************************************************************************************************************
std::mt19937_64& rng()
{
std::mt19937_64 &rng() {
// Do not use for crypto. std::random_device is not good enough.
static std::mt19937_64 generator = std::mt19937_64(std::random_device()());
return generator;
@ -70,17 +68,17 @@ std::mt19937_64& rng()
//****************************************************************************************************************************************************
/// \return user configuration directory used by bridge (based on Golang OS/File's UserConfigDir).
//****************************************************************************************************************************************************
QString userConfigDir()
{
QString userConfigDir() {
QString dir;
#ifdef Q_OS_WIN
dir = qgetenv ("AppData");
if (dir.isEmpty())
throw Exception("%AppData% is not defined.");
#elif defined(Q_OS_IOS) || defined(Q_OS_DARWIN)
dir = qgetenv ("HOME");
if (dir.isEmpty())
dir = qgetenv("HOME");
if (dir.isEmpty()) {
throw Exception("$HOME is not defined.");
}
dir += "/Library/Application Support";
#else
dir = qgetenv ("XDG_CONFIG_HOME");
@ -102,8 +100,7 @@ QString userConfigDir()
//****************************************************************************************************************************************************
/// \return user cache directory used by bridge (based on Golang OS/File's UserCacheDir).
//****************************************************************************************************************************************************
QString userCacheDir()
{
QString userCacheDir() {
QString dir;
#ifdef Q_OS_WIN
@ -111,9 +108,10 @@ QString userCacheDir()
if (dir.isEmpty())
throw Exception("%LocalAppData% is not defined.");
#elif defined(Q_OS_IOS) || defined(Q_OS_DARWIN)
dir = qgetenv ("HOME");
if (dir.isEmpty())
dir = qgetenv("HOME");
if (dir.isEmpty()) {
throw Exception("$HOME is not defined.");
}
dir += "/Library/Caches";
#else
dir = qgetenv ("XDG_CACHE_HOME");
@ -132,11 +130,11 @@ QString userCacheDir()
return folder;
}
//****************************************************************************************************************************************************
/// \return user data directory used by bridge (based on Golang OS/File's UserDataDir).
//****************************************************************************************************************************************************
QString userDataDir()
{
QString userDataDir() {
QString folder;
#ifdef Q_OS_LINUX
@ -157,21 +155,21 @@ QString userDataDir()
return folder;
}
//****************************************************************************************************************************************************
/// \return user logs directory used by bridge.
//****************************************************************************************************************************************************
QString userLogsDir()
{
QString userLogsDir() {
QString const path = QDir(userDataDir()).absoluteFilePath("logs");
QDir().mkpath(path);
return path;
}
//****************************************************************************************************************************************************
/// \return sentry cache directory used by bridge.
//****************************************************************************************************************************************************
QString sentryCacheDir()
{
QString sentryCacheDir() {
QString const path = QDir(userDataDir()).absoluteFilePath("sentry_cache");
QDir().mkpath(path);
return path;
@ -181,8 +179,7 @@ QString sentryCacheDir()
//****************************************************************************************************************************************************
/// \return The value GOOS would return for the current platform.
//****************************************************************************************************************************************************
QString goos()
{
QString goos() {
#if defined(Q_OS_DARWIN)
return "darwin";
#elif defined(Q_OS_WINDOWS)
@ -198,8 +195,7 @@ QString goos()
///
/// \return a random number in the range [0, n-1]
//****************************************************************************************************************************************************
qint64 randN(qint64 n)
{
qint64 randN(qint64 n) {
QMutexLocker locker(&rngMutex);
return (n > 0) ? std::uniform_int_distribution<qint64>(0, n - 1)(rng()) : 0;
}
@ -208,8 +204,7 @@ qint64 randN(qint64 n)
//****************************************************************************************************************************************************
/// \return A random first name.
//****************************************************************************************************************************************************
QString randomFirstName()
{
QString randomFirstName() {
return firstNames[randN(firstNames.size())];
}
@ -217,8 +212,7 @@ QString randomFirstName()
//****************************************************************************************************************************************************
/// \return A random last name.
//****************************************************************************************************************************************************
QString randomLastName()
{
QString randomLastName() {
return lastNames[randN(lastNames.size())];
}
@ -226,15 +220,14 @@ QString randomLastName()
//****************************************************************************************************************************************************
//
//****************************************************************************************************************************************************
SPUser randomUser()
{
SPUser randomUser() {
SPUser user = User::newUser(nullptr);
user->setID(QUuid::createUuid().toString());
QString const firstName = randomFirstName();
QString const lastName = randomLastName();
QString const username = QString("%1.%2").arg(firstName.toLower(), lastName.toLower());
user->setUsername(username);
user->setAddresses(QStringList() << (username + "@proton.me") << (username + "@protonmail.com") );
user->setAddresses(QStringList() << (username + "@proton.me") << (username + "@protonmail.com"));
user->setPassword(QUuid().createUuid().toString(QUuid::StringFormat::WithoutBraces).left(20));
user->setAvatarText(firstName.left(1) + lastName.left(1));
user->setState(UserState::Connected);
@ -249,14 +242,15 @@ SPUser randomUser()
//****************************************************************************************************************************************************
/// \return The OS the application is running on.
//****************************************************************************************************************************************************
OS os()
{
OS os() {
QString const osStr = QSysInfo::productType();
if ((osStr == "macos") || (osStr == "osx")) // Qt < 5 returns "osx", Qt6 returns "macos".
if ((osStr == "macos") || (osStr == "osx")) { // Qt < 5 returns "osx", Qt6 returns "macos".
return OS::MacOS;
}
if (osStr == "windows")
if (osStr == "windows") {
return OS::Windows;
}
return OS::Linux;
}
@ -265,8 +259,7 @@ OS os()
//****************************************************************************************************************************************************
/// \return true if and only if the application is currently running on Linux.
//****************************************************************************************************************************************************
bool onLinux()
{
bool onLinux() {
return OS::Linux == os();
}
@ -274,8 +267,7 @@ bool onLinux()
//****************************************************************************************************************************************************
/// \return true if and only if the application is currently running on MacOS.
//****************************************************************************************************************************************************
bool onMacOS()
{
bool onMacOS() {
return OS::MacOS == os();
}
@ -283,8 +275,7 @@ bool onMacOS()
//****************************************************************************************************************************************************
/// \return true if and only if the application is currently running on Windows.
//****************************************************************************************************************************************************
bool onWindows()
{
bool onWindows() {
return OS::Windows == os();
}

View File

@ -23,8 +23,7 @@
#include <bridgepp/User/User.h>
namespace bridgepp
{
namespace bridgepp {
//****************************************************************************************************************************************************

View File

@ -19,8 +19,7 @@
#include "Exception.h"
namespace bridgepp
{
namespace bridgepp {
//****************************************************************************************************************************************************
@ -28,36 +27,32 @@ namespace bridgepp
//****************************************************************************************************************************************************
Exception::Exception(QString what) noexcept
: std::exception()
, what_(std::move(what))
{
, what_(std::move(what)) {
}
//****************************************************************************************************************************************************
/// \param[in] ref The Exception to copy from
//****************************************************************************************************************************************************
Exception::Exception(Exception const& ref) noexcept
Exception::Exception(Exception const &ref) noexcept
: std::exception(ref)
, what_(ref.what_)
{
, what_(ref.what_) {
}
//****************************************************************************************************************************************************
/// \param[in] ref The Exception to copy from
//****************************************************************************************************************************************************
Exception::Exception(Exception&& ref) noexcept
Exception::Exception(Exception &&ref) noexcept
: std::exception(ref)
, what_(ref.what_)
{
, what_(ref.what_) {
}
//****************************************************************************************************************************************************
/// \return a string describing the exception
//****************************************************************************************************************************************************
QString const& Exception::qwhat() const noexcept
{
QString const &Exception::qwhat() const noexcept {
return what_;
}
@ -65,8 +60,7 @@ QString const& Exception::qwhat() const noexcept
//****************************************************************************************************************************************************
/// \return A pointer to the description string of the exception.
//****************************************************************************************************************************************************
const char* Exception::what() const noexcept
{
const char *Exception::what() const noexcept {
return what_.toLocal8Bit().constData();
}

View File

@ -23,15 +23,13 @@
#include <stdexcept>
namespace bridgepp
{
namespace bridgepp {
//****************************************************************************************************************************************************
/// \brief Exception class.
//****************************************************************************************************************************************************
class Exception : public std::exception
{
class Exception : public std::exception {
public: // member functions
explicit Exception(QString what = QString()) noexcept; ///< Constructor
Exception(Exception const &ref) noexcept; ///< copy constructor

View File

@ -25,8 +25,7 @@ using namespace grpc;
using namespace google::protobuf;
namespace
{
namespace {
Empty empty; ///< Empty protobuf message, re-used across calls.
@ -37,8 +36,7 @@ QString const hostname = "127.0.0.1"; ///< The hostname of the focus service.
}
namespace bridgepp
{
namespace bridgepp {
//****************************************************************************************************************************************************
@ -46,28 +44,29 @@ namespace bridgepp
/// \param[out] outError if not null and the function returns false.
/// \return true iff the connexion was successfully established.
//****************************************************************************************************************************************************
bool FocusGRPCClient::connectToServer(qint64 timeoutMs, QString *outError)
{
try
{
bool FocusGRPCClient::connectToServer(qint64 timeoutMs, QString *outError) {
try {
QString const address = QString("%1:%2").arg(hostname).arg(port);
channel_ = grpc::CreateChannel(address.toStdString(), grpc::InsecureChannelCredentials());
if (!channel_)
if (!channel_) {
throw Exception("Could not create focus service channel.");
}
stub_ = Focus::NewStub(channel_);
if (!channel_->WaitForConnected(gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), gpr_time_from_millis(timeoutMs, GPR_TIMESPAN))))
if (!channel_->WaitForConnected(gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), gpr_time_from_millis(timeoutMs, GPR_TIMESPAN)))) {
throw Exception("Could not connect to focus service");
}
if (channel_->GetState(true) != GRPC_CHANNEL_READY)
if (channel_->GetState(true) != GRPC_CHANNEL_READY) {
throw Exception("Connexion check with focus service failed.");
}
return true;
}
catch (Exception const &e)
{
if (outError)
catch (Exception const &e) {
if (outError) {
*outError = e.qwhat();
}
return false;
}
}
@ -76,8 +75,7 @@ bool FocusGRPCClient::connectToServer(qint64 timeoutMs, QString *outError)
//****************************************************************************************************************************************************
/// \return The status for the call.
//****************************************************************************************************************************************************
grpc::Status FocusGRPCClient::raise()
{
grpc::Status FocusGRPCClient::raise() {
ClientContext ctx;
return stub_->Raise(&ctx, empty, &empty);
}
@ -87,13 +85,13 @@ grpc::Status FocusGRPCClient::raise()
/// \param[out] outVersion The version string.
/// \return The status for the call.
//****************************************************************************************************************************************************
grpc::Status FocusGRPCClient::version(QString &outVersion)
{
grpc::Status FocusGRPCClient::version(QString &outVersion) {
ClientContext ctx;
VersionResponse response;
Status status = stub_->Version(&ctx, empty, &response);
if (status.ok())
if (status.ok()) {
outVersion = QString::fromStdString(response.version());
}
return status;
}

View File

@ -24,15 +24,13 @@
#include "focus.grpc.pb.h"
namespace bridgepp
{
namespace bridgepp {
//**********************************************************************************************************************
/// \brief Focus GRPC client class
//**********************************************************************************************************************
class FocusGRPCClient
{
class FocusGRPCClient {
public: // member functions.
FocusGRPCClient() = default; ///< Default constructor.
FocusGRPCClient(FocusGRPCClient const &) = delete; ///< Disabled copy-constructor.

View File

@ -19,19 +19,16 @@
#include "EventFactory.h"
namespace bridgepp
{
namespace bridgepp {
namespace
{
namespace {
//****************************************************************************************************************************************************
/// \return a new SPStreamEvent
//****************************************************************************************************************************************************
bridgepp::SPStreamEvent newStreamEvent()
{
bridgepp::SPStreamEvent newStreamEvent() {
return std::make_shared<grpc::StreamEvent>();
}
@ -40,8 +37,7 @@ bridgepp::SPStreamEvent newStreamEvent()
/// \param[in] appEvent The app event.
/// \return The stream event.
//****************************************************************************************************************************************************
bridgepp::SPStreamEvent wrapAppEvent(grpc::AppEvent *appEvent)
{
bridgepp::SPStreamEvent wrapAppEvent(grpc::AppEvent *appEvent) {
auto event = newStreamEvent();
event->set_allocated_app(appEvent);
return event;
@ -52,8 +48,7 @@ bridgepp::SPStreamEvent wrapAppEvent(grpc::AppEvent *appEvent)
/// \param[in] loginEvent The login event.
/// \return The stream event.
//****************************************************************************************************************************************************
bridgepp::SPStreamEvent wrapLoginEvent(grpc::LoginEvent *loginEvent)
{
bridgepp::SPStreamEvent wrapLoginEvent(grpc::LoginEvent *loginEvent) {
auto event = newStreamEvent();
event->set_allocated_login(loginEvent);
return event;
@ -64,8 +59,7 @@ bridgepp::SPStreamEvent wrapLoginEvent(grpc::LoginEvent *loginEvent)
/// \param[in] updateEvent The app event.
/// \return The stream event.
//****************************************************************************************************************************************************
bridgepp::SPStreamEvent wrapUpdateEvent(grpc::UpdateEvent *updateEvent)
{
bridgepp::SPStreamEvent wrapUpdateEvent(grpc::UpdateEvent *updateEvent) {
auto event = newStreamEvent();
event->set_allocated_update(updateEvent);
return event;
@ -76,8 +70,7 @@ bridgepp::SPStreamEvent wrapUpdateEvent(grpc::UpdateEvent *updateEvent)
/// \param[in] cacheEvent The cache event.
/// \return The stream event.
//****************************************************************************************************************************************************
bridgepp::SPStreamEvent wrapCacheEvent(grpc::DiskCacheEvent *cacheEvent)
{
bridgepp::SPStreamEvent wrapCacheEvent(grpc::DiskCacheEvent *cacheEvent) {
auto event = newStreamEvent();
event->set_allocated_cache(cacheEvent);
return event;
@ -88,8 +81,7 @@ bridgepp::SPStreamEvent wrapCacheEvent(grpc::DiskCacheEvent *cacheEvent)
/// \param[in] mailSettingsEvent The mail settings event.
/// \return The stream event.
//****************************************************************************************************************************************************
bridgepp::SPStreamEvent wrapMailServerSettingsEvent(grpc::MailServerSettingsEvent *mailServerSettingsEvent)
{
bridgepp::SPStreamEvent wrapMailServerSettingsEvent(grpc::MailServerSettingsEvent *mailServerSettingsEvent) {
auto event = newStreamEvent();
event->set_allocated_mailserversettings(mailServerSettingsEvent);
return event;
@ -100,8 +92,7 @@ bridgepp::SPStreamEvent wrapMailServerSettingsEvent(grpc::MailServerSettingsEven
/// \param[in] keychainEvent The keychain event.
/// \return The stream event.
//****************************************************************************************************************************************************
bridgepp::SPStreamEvent wrapKeychainEvent(grpc::KeychainEvent *keychainEvent)
{
bridgepp::SPStreamEvent wrapKeychainEvent(grpc::KeychainEvent *keychainEvent) {
auto event = newStreamEvent();
event->set_allocated_keychain(keychainEvent);
return event;
@ -112,8 +103,7 @@ bridgepp::SPStreamEvent wrapKeychainEvent(grpc::KeychainEvent *keychainEvent)
/// \param[in] mailEvent The mail event.
/// \return The stream event.
//****************************************************************************************************************************************************
bridgepp::SPStreamEvent wrapMailEvent(grpc::MailEvent *mailEvent)
{
bridgepp::SPStreamEvent wrapMailEvent(grpc::MailEvent *mailEvent) {
auto event = newStreamEvent();
event->set_allocated_mail(mailEvent);
return event;
@ -124,8 +114,7 @@ bridgepp::SPStreamEvent wrapMailEvent(grpc::MailEvent *mailEvent)
/// \param[in] userEvent The user event.
/// \return The stream event.
//****************************************************************************************************************************************************
bridgepp::SPStreamEvent wrapUserEvent(grpc::UserEvent *userEvent)
{
bridgepp::SPStreamEvent wrapUserEvent(grpc::UserEvent *userEvent) {
auto event = newStreamEvent();
event->set_allocated_user(userEvent);
return event;
@ -136,8 +125,7 @@ bridgepp::SPStreamEvent wrapUserEvent(grpc::UserEvent *userEvent)
/// \param[in] genericErrorEvent The generic error event.
/// \return The stream event.
//****************************************************************************************************************************************************
bridgepp::SPStreamEvent wrapGenericErrorEvent(grpc::GenericErrorEvent *genericErrorEvent)
{
bridgepp::SPStreamEvent wrapGenericErrorEvent(grpc::GenericErrorEvent *genericErrorEvent) {
auto event = newStreamEvent();
event->set_allocated_genericerror(genericErrorEvent);
return event;
@ -150,8 +138,7 @@ bridgepp::SPStreamEvent wrapGenericErrorEvent(grpc::GenericErrorEvent *genericEr
/// \param[in] connected The internet status.
/// \return The event.
//****************************************************************************************************************************************************
SPStreamEvent newInternetStatusEvent(bool connected)
{
SPStreamEvent newInternetStatusEvent(bool connected) {
auto *internetStatusEvent = new grpc::InternetStatusEvent();
internetStatusEvent->set_connected(connected);
auto appEvent = new grpc::AppEvent;
@ -163,8 +150,7 @@ SPStreamEvent newInternetStatusEvent(bool connected)
//****************************************************************************************************************************************************
/// \return The event.
//****************************************************************************************************************************************************
SPStreamEvent newToggleAutostartFinishedEvent()
{
SPStreamEvent newToggleAutostartFinishedEvent() {
auto *event = new grpc::ToggleAutostartFinishedEvent;
auto appEvent = new grpc::AppEvent;
appEvent->set_allocated_toggleautostartfinished(event);
@ -175,8 +161,7 @@ SPStreamEvent newToggleAutostartFinishedEvent()
//****************************************************************************************************************************************************
/// \return The event.
//****************************************************************************************************************************************************
SPStreamEvent newResetFinishedEvent()
{
SPStreamEvent newResetFinishedEvent() {
auto event = new grpc::ResetFinishedEvent;
auto appEvent = new grpc::AppEvent;
appEvent->set_allocated_resetfinished(event);
@ -187,8 +172,7 @@ SPStreamEvent newResetFinishedEvent()
//****************************************************************************************************************************************************
/// \return The event.
//****************************************************************************************************************************************************
SPStreamEvent newReportBugFinishedEvent()
{
SPStreamEvent newReportBugFinishedEvent() {
auto event = new grpc::ReportBugFinishedEvent;
auto appEvent = new grpc::AppEvent;
appEvent->set_allocated_reportbugfinished(event);
@ -199,8 +183,7 @@ SPStreamEvent newReportBugFinishedEvent()
//****************************************************************************************************************************************************
/// \return The event.
//****************************************************************************************************************************************************
SPStreamEvent newReportBugSuccessEvent()
{
SPStreamEvent newReportBugSuccessEvent() {
auto event = new grpc::ReportBugSuccessEvent;
auto appEvent = new grpc::AppEvent;
appEvent->set_allocated_reportbugsuccess(event);
@ -211,8 +194,7 @@ SPStreamEvent newReportBugSuccessEvent()
//****************************************************************************************************************************************************
/// \return The event.
//****************************************************************************************************************************************************
SPStreamEvent newReportBugErrorEvent()
{
SPStreamEvent newReportBugErrorEvent() {
auto event = new grpc::ReportBugErrorEvent;
auto appEvent = new grpc::AppEvent;
appEvent->set_allocated_reportbugerror(event);
@ -223,8 +205,7 @@ SPStreamEvent newReportBugErrorEvent()
//****************************************************************************************************************************************************
/// \return The event.
//****************************************************************************************************************************************************
SPStreamEvent newShowMainWindowEvent()
{
SPStreamEvent newShowMainWindowEvent() {
auto event = new grpc::ShowMainWindowEvent;
auto appEvent = new grpc::AppEvent;
appEvent->set_allocated_showmainwindow(event);
@ -237,8 +218,7 @@ SPStreamEvent newShowMainWindowEvent()
/// \param[in] message The message.
/// \return The event.
//****************************************************************************************************************************************************
SPStreamEvent newLoginError(grpc::LoginErrorType error, QString const &message)
{
SPStreamEvent newLoginError(grpc::LoginErrorType error, QString const &message) {
auto event = new ::grpc::LoginErrorEvent;
event->set_type(error);
event->set_message(message.toStdString());
@ -252,8 +232,7 @@ SPStreamEvent newLoginError(grpc::LoginErrorType error, QString const &message)
/// \param[in] username The username.
/// \return The event.
//****************************************************************************************************************************************************
SPStreamEvent newLoginTfaRequestedEvent(QString const &username)
{
SPStreamEvent newLoginTfaRequestedEvent(QString const &username) {
auto event = new ::grpc::LoginTfaRequestedEvent;
event->set_username(username.toStdString());
auto loginEvent = new grpc::LoginEvent;
@ -266,8 +245,7 @@ SPStreamEvent newLoginTfaRequestedEvent(QString const &username)
/// \param[in] username The username.
/// \return The event.
//****************************************************************************************************************************************************
SPStreamEvent newLoginTwoPasswordsRequestedEvent()
{
SPStreamEvent newLoginTwoPasswordsRequestedEvent() {
auto event = new ::grpc::LoginTwoPasswordsRequestedEvent;
auto loginEvent = new grpc::LoginEvent;
loginEvent->set_allocated_twopasswordrequested(event);
@ -280,8 +258,7 @@ SPStreamEvent newLoginTwoPasswordsRequestedEvent()
/// \param[in] wasSignedOut Was the user signed-out.
/// \return The event.
//****************************************************************************************************************************************************
SPStreamEvent newLoginFinishedEvent(QString const &userID, bool wasSignedOut)
{
SPStreamEvent newLoginFinishedEvent(QString const &userID, bool wasSignedOut) {
auto event = new ::grpc::LoginFinishedEvent;
event->set_userid(userID.toStdString());
event->set_wassignedout(wasSignedOut);
@ -295,8 +272,7 @@ SPStreamEvent newLoginFinishedEvent(QString const &userID, bool wasSignedOut)
/// \param[in] userID The userID.
/// \return The event.
//****************************************************************************************************************************************************
SPStreamEvent newLoginAlreadyLoggedInEvent(QString const &userID)
{
SPStreamEvent newLoginAlreadyLoggedInEvent(QString const &userID) {
auto event = new ::grpc::LoginFinishedEvent;
event->set_userid(userID.toStdString());
auto loginEvent = new grpc::LoginEvent;
@ -309,8 +285,7 @@ SPStreamEvent newLoginAlreadyLoggedInEvent(QString const &userID)
/// \param[in] errorType The error type.
/// \return The event.
//****************************************************************************************************************************************************
SPStreamEvent newUpdateErrorEvent(grpc::UpdateErrorType errorType)
{
SPStreamEvent newUpdateErrorEvent(grpc::UpdateErrorType errorType) {
auto event = new grpc::UpdateErrorEvent;
event->set_type(errorType);
auto updateEvent = new grpc::UpdateEvent;
@ -323,8 +298,7 @@ SPStreamEvent newUpdateErrorEvent(grpc::UpdateErrorType errorType)
/// \param[in] version The version.
/// \return The event.
//****************************************************************************************************************************************************
SPStreamEvent newUpdateManualReadyEvent(QString const &version)
{
SPStreamEvent newUpdateManualReadyEvent(QString const &version) {
auto event = new grpc::UpdateManualReadyEvent;
event->set_version(version.toStdString());
auto updateEvent = new grpc::UpdateEvent;
@ -336,8 +310,7 @@ SPStreamEvent newUpdateManualReadyEvent(QString const &version)
//****************************************************************************************************************************************************
/// \return the event.
//****************************************************************************************************************************************************
SPStreamEvent newUpdateManualRestartNeededEvent()
{
SPStreamEvent newUpdateManualRestartNeededEvent() {
auto event = new grpc::UpdateManualRestartNeededEvent;
auto updateEvent = new grpc::UpdateEvent;
updateEvent->set_allocated_manualrestartneeded(event);
@ -349,8 +322,7 @@ SPStreamEvent newUpdateManualRestartNeededEvent()
/// \param[in] version The version.
/// \return The event.
//****************************************************************************************************************************************************
SPStreamEvent newUpdateForceEvent(QString const &version)
{
SPStreamEvent newUpdateForceEvent(QString const &version) {
auto event = new grpc::UpdateForceEvent;
event->set_version(version.toStdString());
auto updateEvent = new grpc::UpdateEvent;
@ -362,8 +334,7 @@ SPStreamEvent newUpdateForceEvent(QString const &version)
//****************************************************************************************************************************************************
/// \return the event.
//****************************************************************************************************************************************************
SPStreamEvent newUpdateSilentRestartNeeded()
{
SPStreamEvent newUpdateSilentRestartNeeded() {
auto event = new grpc::UpdateSilentRestartNeeded;
auto updateEvent = new grpc::UpdateEvent;
updateEvent->set_allocated_silentrestartneeded(event);
@ -374,8 +345,7 @@ SPStreamEvent newUpdateSilentRestartNeeded()
//****************************************************************************************************************************************************
/// \return The event.
//****************************************************************************************************************************************************
SPStreamEvent newUpdateIsLatestVersion()
{
SPStreamEvent newUpdateIsLatestVersion() {
auto event = new grpc::UpdateIsLatestVersion;
auto updateEvent = new grpc::UpdateEvent;
updateEvent->set_allocated_islatestversion(event);
@ -386,8 +356,7 @@ SPStreamEvent newUpdateIsLatestVersion()
//****************************************************************************************************************************************************
/// \return The event.
//****************************************************************************************************************************************************
SPStreamEvent newUpdateCheckFinished()
{
SPStreamEvent newUpdateCheckFinished() {
auto event = new grpc::UpdateCheckFinished;
auto updateEvent = new grpc::UpdateEvent;
updateEvent->set_allocated_checkfinished(event);
@ -399,8 +368,7 @@ SPStreamEvent newUpdateCheckFinished()
/// \param[in] errorType The error type.
/// \return The event.
//****************************************************************************************************************************************************
SPStreamEvent newDiskCacheErrorEvent(grpc::DiskCacheErrorType errorType)
{
SPStreamEvent newDiskCacheErrorEvent(grpc::DiskCacheErrorType errorType) {
auto event = new grpc::DiskCacheErrorEvent;
event->set_type(errorType);
auto cacheEvent = new grpc::DiskCacheEvent;
@ -413,8 +381,7 @@ SPStreamEvent newDiskCacheErrorEvent(grpc::DiskCacheErrorType errorType)
/// \param[in] path The path of the cache.
/// \return The event.
//****************************************************************************************************************************************************
SPStreamEvent newDiskCachePathChangedEvent(QString const &path)
{
SPStreamEvent newDiskCachePathChangedEvent(QString const &path) {
auto event = new grpc::DiskCachePathChangedEvent;
event->set_path(path.toStdString());
auto cacheEvent = new grpc::DiskCacheEvent;
@ -426,20 +393,19 @@ SPStreamEvent newDiskCachePathChangedEvent(QString const &path)
//****************************************************************************************************************************************************
/// \return The event.
//****************************************************************************************************************************************************
SPStreamEvent newDiskCachePathChangeFinishedEvent()
{
SPStreamEvent newDiskCachePathChangeFinishedEvent() {
auto event = new grpc::DiskCachePathChangeFinishedEvent;
auto cacheEvent = new grpc::DiskCacheEvent;
cacheEvent->set_allocated_pathchangefinished(event);
return wrapCacheEvent(cacheEvent);
}
//****************************************************************************************************************************************************
/// \param[in] errorType The error type.
/// \return The event.
//****************************************************************************************************************************************************
SPStreamEvent newMailServerSettingsErrorEvent(grpc::MailServerSettingsErrorType errorType)
{
SPStreamEvent newMailServerSettingsErrorEvent(grpc::MailServerSettingsErrorType errorType) {
auto event = new grpc::MailServerSettingsErrorEvent;
event->set_type(errorType);
auto mailServerSettingsEvent = new grpc::MailServerSettingsEvent;
@ -452,8 +418,7 @@ SPStreamEvent newMailServerSettingsErrorEvent(grpc::MailServerSettingsErrorType
/// \param[in] settings The settings.
/// \return The event.
//****************************************************************************************************************************************************
SPStreamEvent newMailServerSettingsChanged(grpc::ImapSmtpSettings const &settings)
{
SPStreamEvent newMailServerSettingsChanged(grpc::ImapSmtpSettings const &settings) {
auto event = new grpc::MailServerSettingsChangedEvent;
event->set_allocated_settings(new grpc::ImapSmtpSettings(settings));
auto mailServerSettingsEvent = new grpc::MailServerSettingsEvent;
@ -465,8 +430,7 @@ SPStreamEvent newMailServerSettingsChanged(grpc::ImapSmtpSettings const &setting
//****************************************************************************************************************************************************
/// \return The event.
//****************************************************************************************************************************************************
SPStreamEvent newChangeMailServerSettingsFinished()
{
SPStreamEvent newChangeMailServerSettingsFinished() {
auto event = new grpc::ChangeMailServerSettingsFinishedEvent;
auto mailServerSettingsEvent = new grpc::MailServerSettingsEvent;
mailServerSettingsEvent->set_allocated_changemailserversettingsfinished(event);
@ -477,8 +441,7 @@ SPStreamEvent newChangeMailServerSettingsFinished()
//****************************************************************************************************************************************************
/// \return The event.
//****************************************************************************************************************************************************
SPStreamEvent newChangeKeychainFinishedEvent()
{
SPStreamEvent newChangeKeychainFinishedEvent() {
auto event = new grpc::ChangeKeychainFinishedEvent;
auto keychainEvent = new grpc::KeychainEvent;
keychainEvent->set_allocated_changekeychainfinished(event);
@ -489,8 +452,7 @@ SPStreamEvent newChangeKeychainFinishedEvent()
//****************************************************************************************************************************************************
/// \return The event.
//****************************************************************************************************************************************************
SPStreamEvent newHasNoKeychainEvent()
{
SPStreamEvent newHasNoKeychainEvent() {
auto event = new grpc::HasNoKeychainEvent;
auto keychainEvent = new grpc::KeychainEvent;
keychainEvent->set_allocated_hasnokeychain(event);
@ -501,8 +463,7 @@ SPStreamEvent newHasNoKeychainEvent()
//****************************************************************************************************************************************************
/// \return The event.
//****************************************************************************************************************************************************
SPStreamEvent newRebuildKeychainEvent()
{
SPStreamEvent newRebuildKeychainEvent() {
auto event = new grpc::RebuildKeychainEvent;
auto keychainEvent = new grpc::KeychainEvent;
keychainEvent->set_allocated_rebuildkeychain(event);
@ -514,8 +475,7 @@ SPStreamEvent newRebuildKeychainEvent()
/// \param[in] email The email.
/// \return The event.
//****************************************************************************************************************************************************
SPStreamEvent newNoActiveKeyForRecipientEvent(QString const &email)
{
SPStreamEvent newNoActiveKeyForRecipientEvent(QString const &email) {
auto event = new grpc::NoActiveKeyForRecipientEvent;
event->set_email(email.toStdString());
auto mailEvent = new grpc::MailEvent;
@ -528,8 +488,7 @@ SPStreamEvent newNoActiveKeyForRecipientEvent(QString const &email)
/// \param[in] address The address.
/// /// \return The event.
//****************************************************************************************************************************************************
SPStreamEvent newAddressChangedEvent(QString const &address)
{
SPStreamEvent newAddressChangedEvent(QString const &address) {
auto event = new grpc::AddressChangedEvent;
event->set_address(address.toStdString());
auto mailEvent = new grpc::MailEvent;
@ -542,8 +501,7 @@ SPStreamEvent newAddressChangedEvent(QString const &address)
/// \param[in] address The address.
/// \return The event.
//****************************************************************************************************************************************************
SPStreamEvent newAddressChangedLogoutEvent(QString const &address)
{
SPStreamEvent newAddressChangedLogoutEvent(QString const &address) {
auto event = new grpc::AddressChangedLogoutEvent;
event->set_address(address.toStdString());
auto mailEvent = new grpc::MailEvent;
@ -555,8 +513,7 @@ SPStreamEvent newAddressChangedLogoutEvent(QString const &address)
//****************************************************************************************************************************************************
/// \return The event.
//****************************************************************************************************************************************************
SPStreamEvent newApiCertIssueEvent()
{
SPStreamEvent newApiCertIssueEvent() {
auto event = new grpc::ApiCertIssueEvent;
auto mailEvent = new grpc::MailEvent;
mailEvent->set_allocated_apicertissue(event);
@ -568,8 +525,7 @@ SPStreamEvent newApiCertIssueEvent()
/// \param[in] userID The userID.
/// \return The event.
//****************************************************************************************************************************************************
SPStreamEvent newToggleSplitModeFinishedEvent(QString const &userID)
{
SPStreamEvent newToggleSplitModeFinishedEvent(QString const &userID) {
auto event = new grpc::ToggleSplitModeFinishedEvent;
event->set_userid(userID.toStdString());
auto userEvent = new grpc::UserEvent;
@ -582,8 +538,7 @@ SPStreamEvent newToggleSplitModeFinishedEvent(QString const &userID)
/// \param[in] username The username.
/// /// \return The event.
//****************************************************************************************************************************************************
SPStreamEvent newUserDisconnectedEvent(QString const &username)
{
SPStreamEvent newUserDisconnectedEvent(QString const &username) {
auto event = new grpc::UserDisconnectedEvent;
event->set_username(username.toStdString());
auto userEvent = new grpc::UserEvent;
@ -596,8 +551,7 @@ SPStreamEvent newUserDisconnectedEvent(QString const &username)
/// \param[in] userID The userID.
/// \return The event.
//****************************************************************************************************************************************************
SPStreamEvent newUserChangedEvent(QString const &userID)
{
SPStreamEvent newUserChangedEvent(QString const &userID) {
auto event = new grpc::UserChangedEvent;
event->set_userid(userID.toStdString());
auto userEvent = new grpc::UserEvent;
@ -610,8 +564,7 @@ SPStreamEvent newUserChangedEvent(QString const &userID)
/// \param[in] errorCode The error errorCode.
/// \return The event.
//****************************************************************************************************************************************************
SPStreamEvent newGenericErrorEvent(grpc::ErrorCode errorCode)
{
SPStreamEvent newGenericErrorEvent(grpc::ErrorCode errorCode) {
auto event = new grpc::GenericErrorEvent;
event->set_code(errorCode);
return wrapGenericErrorEvent(event);

View File

@ -24,8 +24,7 @@
#include "GRPCUtils.h"
namespace bridgepp
{
namespace bridgepp {
// App events

View File

@ -28,8 +28,7 @@
#include "grpc++/grpc++.h"
namespace bridgepp
{
namespace bridgepp {
typedef grpc::Status (grpc::Bridge::Stub::*SimpleMethod)(grpc::ClientContext *, const google::protobuf::Empty &, google::protobuf::Empty *);
@ -46,8 +45,7 @@ typedef std::unique_ptr<grpc::ClientContext> UPClientContext;
//****************************************************************************************************************************************************
/// \brief gRPC client class. This class encapsulate the gRPC service, abstracting all data type conversions.
//****************************************************************************************************************************************************
class GRPCClient : public QObject
{
class GRPCClient : public QObject {
Q_OBJECT
public: // static member functions
static void removeServiceConfigFile(); ///< Delete the service config file.
@ -209,7 +207,7 @@ public:
grpc::Status stopEventStreamReader(); ///< Stop the event stream.
private:
void log(Log::Level level, QString const & message); ///< Log an event.
void log(Log::Level level, QString const &message); ///< Log an event.
void logTrace(QString const &message); ///< Log a trace event.
void logDebug(QString const &message); ///< Log a debug event.
void logError(QString const &message); ///< Log an error event.

View File

@ -23,8 +23,7 @@
using namespace bridgepp;
namespace
{
namespace {
Exception const invalidFileException("The service configuration file is invalid"); // Exception for invalid config.
Exception const couldNotSaveException("The service configuration file could not be saved"); ///< Exception for write errors.
@ -42,11 +41,11 @@ QString const keyFileSocketPath = "fileSocketPath"; ///< The JSON key for the fi
/// \param[in] object The JSON object containing the value.
/// \param[in] key The key under which the value is stored.
//****************************************************************************************************************************************************
QString jsonStringValue(QJsonObject const &object, QString const &key)
{
QString jsonStringValue(QJsonObject const &object, QString const &key) {
QJsonValue const v = object[key];
if (!v.isString())
if (!v.isString()) {
throw invalidFileException;
}
return v.toString();
}
@ -59,11 +58,11 @@ QString jsonStringValue(QJsonObject const &object, QString const &key)
/// \param[in] object The JSON object containing the value.
/// \param[in] key The key under which the value is stored.
//****************************************************************************************************************************************************
qint32 jsonIntValue(QJsonObject const &object, QString const &key)
{
qint32 jsonIntValue(QJsonObject const &object, QString const &key) {
QJsonValue const v = object[key];
if (!v.isDouble())
if (!v.isDouble()) {
throw invalidFileException;
}
return v.toInt();
}
@ -76,13 +75,12 @@ qint32 jsonIntValue(QJsonObject const &object, QString const &key)
/// \param[out] outError if not null and an error occurs, this variable contains a description of the error.
/// \return true iff the operation was successful.
//****************************************************************************************************************************************************
bool GRPCConfig::load(QString const &path, QString *outError)
{
try
{
bool GRPCConfig::load(QString const &path, QString *outError) {
try {
QFile file(path);
if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
throw Exception("Could not open gRPC service config file.");
}
QJsonDocument const doc = QJsonDocument::fromJson(file.readAll());
QJsonObject const object = doc.object();
@ -93,10 +91,10 @@ bool GRPCConfig::load(QString const &path, QString *outError)
return true;
}
catch (Exception const &e)
{
if (outError)
catch (Exception const &e) {
if (outError) {
*outError = e.qwhat();
}
return false;
}
}
@ -107,10 +105,8 @@ bool GRPCConfig::load(QString const &path, QString *outError)
/// \param[out] outError if not null and an error occurs, this variable contains a description of the error.
/// \return true iff the operation was successful.
//****************************************************************************************************************************************************
bool GRPCConfig::save(QString const &path, QString *outError)
{
try
{
bool GRPCConfig::save(QString const &path, QString *outError) {
try {
QJsonObject object;
object.insert(keyPort, port);
object.insert(keyCert, cert);
@ -118,19 +114,21 @@ bool GRPCConfig::save(QString const &path, QString *outError)
object.insert(keyFileSocketPath, fileSocketPath);
QFile file(path);
if (!file.open(QIODevice::WriteOnly | QIODevice::Text))
if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
throw couldNotSaveException;
}
QByteArray const array = QJsonDocument(object).toJson();
if (array.size() != file.write(array))
if (array.size() != file.write(array)) {
throw couldNotSaveException;
}
return true;
}
catch (Exception const &e)
{
if (outError)
catch (Exception const &e) {
if (outError) {
*outError = e.qwhat();
}
return false;
}
}

View File

@ -23,8 +23,7 @@
//****************************************************************************************************************************************************
/// Service configuration class.
//****************************************************************************************************************************************************
struct GRPCConfig
{
struct GRPCConfig {
public: // data members
qint32 port; ///< The port.
QString cert; ///< The server TLS certificate.
@ -36,5 +35,4 @@ public: // data members
};
#endif //BRIDGE_PP_GRPC_CONFIG_H

View File

@ -22,12 +22,10 @@
using namespace grpc;
namespace bridgepp
{
namespace bridgepp {
namespace
{
namespace {
ErrorInfo const unknownError { UNKNOWN_ERROR, QObject::tr("Unknown error"), QObject::tr("An unknown error occurred.") }; // Unknown error
@ -36,7 +34,7 @@ ErrorInfo const unknownError { UNKNOWN_ERROR, QObject::tr("Unknown error"), QObj
QList<ErrorInfo> const errorList {
unknownError,
{ TLS_CERT_EXPORT_ERROR, QObject::tr("Export error"), QObject::tr("The TLS certificate could not be exported.") },
{ TLS_KEY_EXPORT_ERROR, QObject::tr("Export error"), QObject::tr("The TLS private key could not be exported.") },
{ TLS_KEY_EXPORT_ERROR, QObject::tr("Export error"), QObject::tr("The TLS private key could not be exported.") },
};
@ -46,9 +44,8 @@ QList<ErrorInfo> const errorList {
//****************************************************************************************************************************************************
/// \param[in] error
//****************************************************************************************************************************************************
ErrorInfo errorInfo(grpc::ErrorCode code)
{
QList<ErrorInfo>::const_iterator it = std::find_if(errorList.begin(), errorList.end(), [code](ErrorInfo info) -> bool { return code == info.code;});
ErrorInfo errorInfo(grpc::ErrorCode code) {
QList<ErrorInfo>::const_iterator it = std::find_if(errorList.begin(), errorList.end(), [code](ErrorInfo info) -> bool { return code == info.code; });
return errorList.end() == it ? unknownError : *it;
}

View File

@ -22,22 +22,19 @@
#include "../BridgeUtils.h"
namespace bridgepp
{
namespace bridgepp {
std::string const grpcMetadataServerTokenKey = "server-token";
namespace
{
namespace {
//****************************************************************************************************************************************************
/// \return the gRPC server config file name
//****************************************************************************************************************************************************
QString grpcServerConfigFilename()
{
QString grpcServerConfigFilename() {
return "grpcServerConfig.json";
}
@ -45,8 +42,7 @@ QString grpcServerConfigFilename()
//****************************************************************************************************************************************************
/// \return the gRPC client config file name
//****************************************************************************************************************************************************
QString grpcClientConfigBaseFilename()
{
QString grpcClientConfigBaseFilename() {
return "grpcClientConfig_%1.json";
}
@ -54,8 +50,7 @@ QString grpcClientConfigBaseFilename()
//****************************************************************************************************************************************************
/// \return The server certificate file name
//****************************************************************************************************************************************************
QString serverCertificateFilename()
{
QString serverCertificateFilename() {
return "cert.pem";
}
@ -63,8 +58,7 @@ QString serverCertificateFilename()
//****************************************************************************************************************************************************
//
//****************************************************************************************************************************************************
QString serverKeyFilename()
{
QString serverKeyFilename() {
return "key.pem";
}
@ -83,8 +77,7 @@ bool useFileSocketForGRPC() {
//****************************************************************************************************************************************************
/// \return The absolute path of the service config path.
//****************************************************************************************************************************************************
QString grpcServerConfigPath()
{
QString grpcServerConfigPath() {
return QDir(userConfigDir()).absoluteFilePath(grpcServerConfigFilename());
}
@ -92,8 +85,7 @@ QString grpcServerConfigPath()
//****************************************************************************************************************************************************
/// \return The absolute path of the service config path.
//****************************************************************************************************************************************************
QString grpcClientConfigBasePath()
{
QString grpcClientConfigBasePath() {
return QDir(userConfigDir()).absoluteFilePath(grpcClientConfigBaseFilename());
}
@ -101,8 +93,7 @@ QString grpcClientConfigBasePath()
//****************************************************************************************************************************************************
/// \return The absolute path of the server certificate.
//****************************************************************************************************************************************************
QString serverCertificatePath()
{
QString serverCertificatePath() {
return QDir(userConfigDir()).absoluteFilePath(serverCertificateFilename());
}
@ -110,8 +101,7 @@ QString serverCertificatePath()
//****************************************************************************************************************************************************
/// \return The absolute path of the server key.
//****************************************************************************************************************************************************
QString serverKeyPath()
{
QString serverKeyPath() {
return QDir(userConfigDir()).absoluteFilePath(serverKeyFilename());
}
@ -122,19 +112,18 @@ QString serverKeyPath()
/// \return The path of the created file.
/// \return A null string if the file could not be saved..
//****************************************************************************************************************************************************
QString createClientConfigFile(QString const &token)
{
QString createClientConfigFile(QString const &token) {
QString const basePath = grpcClientConfigBasePath();
QString path, error;
for (qint32 i = 0; i < 1000; ++i) // we try a decent amount of times
{
path = basePath.arg(i);
if (!QFileInfo(path).exists())
{
if (!QFileInfo(path).exists()) {
GRPCConfig config;
config.token = token;
if (!config.save(path))
if (!config.save(path)) {
return QString();
}
return path;
}
}
@ -147,10 +136,8 @@ QString createClientConfigFile(QString const &token)
/// \param[in] level The Log::Level.
/// \return The grpc::LogLevel.
//****************************************************************************************************************************************************
grpc::LogLevel logLevelToGRPC(Log::Level level)
{
switch (level)
{
grpc::LogLevel logLevelToGRPC(Log::Level level) {
switch (level) {
case Log::Level::Panic:
return grpc::LogLevel::LOG_PANIC;
case Log::Level::Fatal:
@ -175,10 +162,8 @@ grpc::LogLevel logLevelToGRPC(Log::Level level)
/// \param[in] level The level::LogLevel.
/// \return The Log::Level.
//****************************************************************************************************************************************************
Log::Level logLevelFromGRPC(grpc::LogLevel level)
{
switch (level)
{
Log::Level logLevelFromGRPC(grpc::LogLevel level) {
switch (level) {
case grpc::LOG_PANIC:
return Log::Level::Panic;
case grpc::LOG_FATAL:
@ -203,10 +188,8 @@ Log::Level logLevelFromGRPC(grpc::LogLevel level)
/// \param[in] state The user state.
/// \return The gRPC user state.
//****************************************************************************************************************************************************
grpc::UserState userStateToGRPC(UserState state)
{
switch (state)
{
grpc::UserState userStateToGRPC(UserState state) {
switch (state) {
case UserState::SignedOut:
return grpc::UserState::SIGNED_OUT;
case UserState::Locked:
@ -223,16 +206,14 @@ grpc::UserState userStateToGRPC(UserState state)
/// \param[in] state The gRPC user state
/// \return the user state
//****************************************************************************************************************************************************
UserState userStateFromGRPC(grpc::UserState state)
{
switch (state)
{
UserState userStateFromGRPC(grpc::UserState state) {
switch (state) {
case grpc::UserState::SIGNED_OUT:
return UserState::SignedOut;
case grpc::UserState::LOCKED:
return UserState::Locked;
case grpc::UserState::CONNECTED:
return UserState ::Connected;
return UserState::Connected;
default:
throw Exception(QString("unknown gRPC user state %1.").arg(qint32(state)));
}
@ -243,16 +224,16 @@ UserState userStateFromGRPC(grpc::UserState state)
/// \param[in] grpcUser The gRPC user.
/// \return user The user.
//****************************************************************************************************************************************************
SPUser userFromGRPC(grpc::User const &grpcUser)
{
SPUser userFromGRPC(grpc::User const &grpcUser) {
SPUser user = User::newUser(nullptr);
user->setID(QString::fromStdString(grpcUser.id()));
user->setUsername(QString::fromStdString(grpcUser.username()));
user->setPassword(QString::fromStdString(grpcUser.password()));
QStringList addresses;
for (int j = 0; j < grpcUser.addresses_size(); ++j)
for (int j = 0; j < grpcUser.addresses_size(); ++j) {
addresses.append(QString::fromStdString(grpcUser.addresses(j)));
}
user->setAddresses(addresses);
user->setAvatarText(QString::fromStdString(grpcUser.avatartext()));
user->setState(userStateFromGRPC(grpcUser.state()));
@ -268,14 +249,14 @@ SPUser userFromGRPC(grpc::User const &grpcUser)
/// \param[in] user the user.
/// \param[out] outGRPCUser The GRPC user.
//****************************************************************************************************************************************************
void userToGRPC(User const &user, grpc::User &outGRPCUser)
{
void userToGRPC(User const &user, grpc::User &outGRPCUser) {
outGRPCUser.set_id(user.id().toStdString());
outGRPCUser.set_username(user.username().toStdString());
outGRPCUser.set_password(user.password().toStdString());
outGRPCUser.clear_addresses();
for (QString const& address: user.addresses())
for (QString const &address: user.addresses()) {
outGRPCUser.add_addresses(address.toStdString());
}
outGRPCUser.set_avatartext(user.avatarText().toStdString());
outGRPCUser.set_state(userStateToGRPC(user.state()));
outGRPCUser.set_splitmode(user.splitMode());
@ -288,14 +269,14 @@ void userToGRPC(User const &user, grpc::User &outGRPCUser)
/// \return The path to a file that can be used for a gRPC file socket.
/// \return A null string if no path could be found.
//****************************************************************************************************************************************************
QString getAvailableFileSocketPath()
{
QString getAvailableFileSocketPath() {
QDir const tempDir(QStandardPaths::writableLocation(QStandardPaths::TempLocation));
for (qint32 i = 0; i < 10000; i++) {
QString const path = tempDir.absoluteFilePath(QString("bridge_%1.sock").arg(qint32(i), 4, 10, QChar('0')));
QFile f(path);
if ((!f.exists()) || f.remove())
if ((!f.exists()) || f.remove()) {
return path;
}
}
return QString();

View File

@ -25,8 +25,7 @@
#include "bridge.grpc.pb.h"
namespace bridgepp
{
namespace bridgepp {
extern std::string const grpcMetadataServerTokenKey; ///< The key for the server token stored in the gRPC calls context metadata.

View File

@ -20,12 +20,10 @@
#include "../Exception/Exception.h"
namespace bridgepp
{
namespace bridgepp {
namespace
{
namespace {
Log *qtHandlerLog { nullptr }; ///< The log instance handling qt logs.
QMutex qtHandlerMutex; ///< A mutex used to access qtHandlerLog.
@ -45,8 +43,7 @@ QList<QPair<Log::Level, QString>> const logLevelStrings {
//****************************************************************************************************************************************************
/// \param[in] log The log handling qt log entries. Can be null.
//****************************************************************************************************************************************************
void setQtMessageHandlerLog(Log *log)
{
void setQtMessageHandlerLog(Log *log) {
QMutexLocker locker(&qtHandlerMutex);
qtHandlerLog = log;
}
@ -55,8 +52,7 @@ void setQtMessageHandlerLog(Log *log)
//****************************************************************************************************************************************************
/// \return The log handling qt log entries. Can be null.
//****************************************************************************************************************************************************
Log *qtMessageHandlerLog()
{
Log *qtMessageHandlerLog() {
QMutexLocker locker(&qtHandlerMutex);
return qtHandlerLog;
}
@ -66,13 +62,12 @@ Log *qtMessageHandlerLog()
/// \param[in] type The message type.
/// \param[in] message The message.
//****************************************************************************************************************************************************
void qtMessageHandler(QtMsgType type, QMessageLogContext const &, QString const &message)
{
void qtMessageHandler(QtMsgType type, QMessageLogContext const &, QString const &message) {
Log *log = qtMessageHandlerLog();
if (!log)
if (!log) {
return;
switch (type)
{
}
switch (type) {
case QtDebugMsg:
log->debug(message);
break;
@ -102,8 +97,7 @@ void qtMessageHandler(QtMsgType type, QMessageLogContext const &, QString const
/// \param[in] message The log entry message.
/// \return The string for the log entry
//****************************************************************************************************************************************************
QString Log::logEntryToString(Log::Level level, QDateTime const &dateTime, QString const &message)
{
QString Log::logEntryToString(Log::Level level, QDateTime const &dateTime, QString const &message) {
return QString("%1[%2] %3").arg(levelToString(level).left(4).toUpper(), dateTime.toString("MMM dd HH:mm:ss.zzz"), message);
}
@ -112,8 +106,7 @@ QString Log::logEntryToString(Log::Level level, QDateTime const &dateTime, QStri
/// \param[in] level The level.
/// \return A string describing the level.
//****************************************************************************************************************************************************
QString Log::levelToString(Log::Level level)
{
QString Log::levelToString(Log::Level level) {
QList<QPair<Log::Level, QString>>::const_iterator it = std::find_if(logLevelStrings.begin(), logLevelStrings.end(),
[&level](QPair<Log::Level, QString> const &pair) -> bool {
return pair.first == level;
@ -129,16 +122,16 @@ QString Log::levelToString(Log::Level level)
/// \param[out] outLevel The log level parsed. if not found, the value of the variable is not modified.
/// \return true iff parsing was successful.
//****************************************************************************************************************************************************
bool Log::stringToLevel(QString const &str, Log::Level &outLevel)
{
bool Log::stringToLevel(QString const &str, Log::Level &outLevel) {
QList<QPair<Log::Level, QString>>::const_iterator it = std::find_if(logLevelStrings.begin(), logLevelStrings.end(),
[&str](QPair<Log::Level, QString> const &pair) -> bool {
return 0 == QString::compare(str, pair.second, Qt::CaseInsensitive);
});
bool const found = (it != logLevelStrings.end());
if (found)
if (found) {
outLevel = it->first;
}
return found;
}
@ -147,8 +140,7 @@ bool Log::stringToLevel(QString const &str, Log::Level &outLevel)
//****************************************************************************************************************************************************
/// the message handle process the message from the Qt logging system.
//****************************************************************************************************************************************************
void Log::registerAsQtMessageHandler()
{
void Log::registerAsQtMessageHandler() {
setQtMessageHandlerLog(this);
qInstallMessageHandler(qtMessageHandler);
}
@ -160,16 +152,14 @@ void Log::registerAsQtMessageHandler()
Log::Log()
: QObject()
, stdout_(stdout)
, stderr_(stderr)
{
, stderr_(stderr) {
}
//****************************************************************************************************************************************************
/// \param[in] level The log level.
//****************************************************************************************************************************************************
void Log::setLevel(Log::Level level)
{
void Log::setLevel(Log::Level level) {
QMutexLocker locker(&mutex_);
level_ = level;
}
@ -178,8 +168,7 @@ void Log::setLevel(Log::Level level)
//****************************************************************************************************************************************************
/// \return The log level.
//****************************************************************************************************************************************************
Log::Level Log::level() const
{
Log::Level Log::level() const {
QMutexLocker locker(&mutex_);
return level_;
}
@ -188,8 +177,7 @@ Log::Level Log::level() const
//****************************************************************************************************************************************************
/// \param[in] value Should the log entries be sent to STDOUT/STDERR.
//****************************************************************************************************************************************************
void Log::setEchoInConsole(bool value)
{
void Log::setEchoInConsole(bool value) {
QMutexLocker locker(&mutex_);
echoInConsole_ = value;
}
@ -198,8 +186,7 @@ void Log::setEchoInConsole(bool value)
//****************************************************************************************************************************************************
/// \return true iff the log entries be should sent to STDOUT/STDERR.
//****************************************************************************************************************************************************
bool Log::echoInConsole() const
{
bool Log::echoInConsole() const {
QMutexLocker locker(&mutex_);
return echoInConsole_;
}
@ -210,15 +197,16 @@ bool Log::echoInConsole() const
/// \param[out] outError if an error occurs and this pointer in not null, on exit it contains a description of the error.
/// \return true if and only if the operation was successful.
//****************************************************************************************************************************************************
bool Log::startWritingToFile(QString const &path, QString *outError)
{
bool Log::startWritingToFile(QString const &path, QString *outError) {
QMutexLocker locker(&mutex_);
file_ = std::make_unique<QFile>(path);
if (file_->open(QIODevice::WriteOnly | QIODevice::Text))
if (file_->open(QIODevice::WriteOnly | QIODevice::Text)) {
return true;
}
if (outError)
if (outError) {
*outError = QString("Could not open log file '%1' for writing.");
}
file_.reset();
return false;
}
@ -227,8 +215,7 @@ bool Log::startWritingToFile(QString const &path, QString *outError)
//****************************************************************************************************************************************************
///
//****************************************************************************************************************************************************
void Log::stopWritingToFile()
{
void Log::stopWritingToFile() {
QMutexLocker locker(&mutex_);
file_.reset();
}
@ -237,8 +224,7 @@ void Log::stopWritingToFile()
//****************************************************************************************************************************************************
/// \param[in] message The message.
//****************************************************************************************************************************************************
void Log::panic(QString const &message)
{
void Log::panic(QString const &message) {
return this->addEntry(Level::Panic, message);
}
@ -246,8 +232,7 @@ void Log::panic(QString const &message)
//****************************************************************************************************************************************************
/// \param[in] message The message.
//****************************************************************************************************************************************************
void Log::fatal(QString const &message)
{
void Log::fatal(QString const &message) {
return this->addEntry(Level::Fatal, message);
}
@ -255,8 +240,7 @@ void Log::fatal(QString const &message)
//****************************************************************************************************************************************************
/// \param[in] message The message.
//****************************************************************************************************************************************************
void Log::error(QString const &message)
{
void Log::error(QString const &message) {
return this->addEntry(Level::Error, message);
}
@ -264,8 +248,7 @@ void Log::error(QString const &message)
//****************************************************************************************************************************************************
/// \param[in] message The message.
//****************************************************************************************************************************************************
void Log::warn(QString const &message)
{
void Log::warn(QString const &message) {
return this->addEntry(Level::Warn, message);
}
@ -273,8 +256,7 @@ void Log::warn(QString const &message)
//****************************************************************************************************************************************************
/// \param[in] message The message.
//****************************************************************************************************************************************************
void Log::info(QString const &message)
{
void Log::info(QString const &message) {
return this->addEntry(Level::Info, message);
}
@ -282,8 +264,7 @@ void Log::info(QString const &message)
//****************************************************************************************************************************************************
/// \param[in] message The message.
//****************************************************************************************************************************************************
void Log::debug(QString const &message)
{
void Log::debug(QString const &message) {
return this->addEntry(Level::Debug, message);
}
@ -291,8 +272,7 @@ void Log::debug(QString const &message)
//****************************************************************************************************************************************************
/// \param[in] message The message.
//****************************************************************************************************************************************************
void Log::trace(QString const &message)
{
void Log::trace(QString const &message) {
return this->addEntry(Level::Trace, message);
}
@ -301,28 +281,27 @@ void Log::trace(QString const &message)
/// \param[in] level The level.
/// \param[in] message The message.
//****************************************************************************************************************************************************
void Log::addEntry(Log::Level level, QString const &message)
{
void Log::addEntry(Log::Level level, QString const &message) {
QDateTime const dateTime = QDateTime::currentDateTime();
QMutexLocker locker(&mutex_);
if (qint32(level) > qint32(level_))
if (qint32(level) > qint32(level_)) {
return;
}
emit entryAdded(level, message);
if (!(echoInConsole_ || file_))
if (!(echoInConsole_ || file_)) {
return;
}
QString const entryStr = logEntryToString(level, dateTime, message) + "\n";
if (echoInConsole_)
{
if (echoInConsole_) {
QTextStream &stream = (qint32(level) <= (qint32(Level::Warn))) ? stderr_ : stdout_;
stream << entryStr;
stream.flush();
}
if (file_)
{
if (file_) {
file_->write(entryStr.toLocal8Bit());
file_->flush();
}

View File

@ -20,20 +20,17 @@
#define BRIDGE_PP_LOG_H
namespace bridgepp
{
namespace bridgepp {
//****************************************************************************************************************************************************
/// \brief Basic log class. No logging to file. Four levels. Rebroadcast received log entries via Qt signals.
//****************************************************************************************************************************************************
class Log : public QObject
{
class Log : public QObject {
Q_OBJECT
public: // data types.
/// \brief Log level class. The list matches [loggers log levels](https://pkg.go.dev/github.com/sirupsen/logrus).
enum class Level
{
enum class Level {
Panic, ///< Panic log level.
Fatal, ///< Fatal log level.
Error, ///< Error log level.
@ -46,7 +43,7 @@ public: // data types.
public: // static member functions.
static QString logEntryToString(Log::Level level, QDateTime const &dateTime, QString const &message); ///< Return a string describing a log entry.
static QString levelToString(Log::Level level); ///< return the string for a level.
static bool stringToLevel(QString const &str, Log::Level& outLevel); ///< parse a level from a string.
static bool stringToLevel(QString const &str, Log::Level &outLevel); ///< parse a level from a string.
public: // static data member.
static const Level defaultLevel { Level::Info }; ///< The default log level (the same as logrus).
@ -63,7 +60,7 @@ public: // member functions.
Level level() const; ///< Get the log level.
void setEchoInConsole(bool value); ///< Set if the log entries should be echoed in STDOUT/STDERR.
bool echoInConsole() const; ///< Check if the log entries should be echoed in STDOUT/STDERR.
bool startWritingToFile(QString const& path, QString *outError = nullptr); ///< Start writing the log to file. Concerns only future entries.
bool startWritingToFile(QString const &path, QString *outError = nullptr); ///< Start writing the log to file. Concerns only future entries.
void stopWritingToFile();
void registerAsQtMessageHandler(); ///< Install the Qt message handler.

View File

@ -20,8 +20,7 @@
#include "Exception/Exception.h"
namespace bridgepp
{
namespace bridgepp {
//****************************************************************************************************************************************************
@ -34,13 +33,14 @@ ProcessMonitor::ProcessMonitor(QString const &exePath, QStringList const &args,
, exePath_(exePath)
, args_(args)
, out_(stdout)
, err_(stderr)
{
, err_(stderr) {
QFileInfo fileInfo(exePath);
if (!fileInfo.exists())
if (!fileInfo.exists()) {
throw Exception(QString("Could not locate %1 executable.").arg(fileInfo.baseName()));
if ((!fileInfo.isFile()) || (!fileInfo.isExecutable()))
}
if ((!fileInfo.isFile()) || (!fileInfo.isExecutable())) {
throw Exception(QString("Invalid %1 executable").arg(fileInfo.baseName()));
}
}
@ -49,15 +49,13 @@ ProcessMonitor::ProcessMonitor(QString const &exePath, QStringList const &args,
//****************************************************************************************************************************************************
void ProcessMonitor::forwardProcessOutput(QProcess &p) {
QByteArray array = p.readAllStandardError();
if (!array.isEmpty())
{
if (!array.isEmpty()) {
err_ << array;
err_.flush();
}
array = p.readAllStandardOutput();
if (!array.isEmpty())
{
if (!array.isEmpty()) {
out_ << array;
out_.flush();
}
@ -67,10 +65,8 @@ void ProcessMonitor::forwardProcessOutput(QProcess &p) {
//****************************************************************************************************************************************************
//
//****************************************************************************************************************************************************
void ProcessMonitor::run()
{
try
{
void ProcessMonitor::run() {
try {
{
QMutexLocker locker(&statusMutex_);
status_.ended = false;
@ -88,8 +84,7 @@ void ProcessMonitor::run()
status_.pid = p.processId();
}
while (!p.waitForFinished(100))
{
while (!p.waitForFinished(100)) {
this->forwardProcessOutput(p);
}
this->forwardProcessOutput(p);
@ -101,8 +96,7 @@ void ProcessMonitor::run()
emit processExited(status_.returnCode);
emit finished();
}
catch (Exception const &e)
{
catch (Exception const &e) {
emit error(e.qwhat());
}
}
@ -111,8 +105,7 @@ void ProcessMonitor::run()
//****************************************************************************************************************************************************
/// \return status of the monitored process
//****************************************************************************************************************************************************
const ProcessMonitor::MonitorStatus ProcessMonitor::getStatus()
{
const ProcessMonitor::MonitorStatus ProcessMonitor::getStatus() {
QMutexLocker locker(&statusMutex_);
return status_;
}

View File

@ -23,19 +23,16 @@
#include "Worker/Worker.h"
namespace bridgepp
{
namespace bridgepp {
//**********************************************************************************************************************
/// \brief Process launcher and monitor class.
//**********************************************************************************************************************
class ProcessMonitor : public Worker
{
class ProcessMonitor : public Worker {
Q_OBJECT
public: // static member functions
struct MonitorStatus
{
struct MonitorStatus {
bool ended = false;
int returnCode = 0;
qint64 pid = 0;

View File

@ -19,15 +19,13 @@
#include "User.h"
namespace bridgepp
{
namespace bridgepp {
//****************************************************************************************************************************************************
/// \param[in] parent The parent object of the user.
//****************************************************************************************************************************************************
SPUser User::newUser(QObject *parent)
{
SPUser User::newUser(QObject *parent) {
return SPUser(new User(parent));
}
@ -36,8 +34,7 @@ SPUser User::newUser(QObject *parent)
/// \param[in] parent The parent object.
//****************************************************************************************************************************************************
User::User(QObject *parent)
: QObject(parent)
{
: QObject(parent) {
}
@ -45,8 +42,7 @@ User::User(QObject *parent)
//****************************************************************************************************************************************************
/// \param[in] user The user to copy from
//****************************************************************************************************************************************************
void User::update(User const &user)
{
void User::update(User const &user) {
this->setID(user.id());
this->setUsername(user.username());
this->setPassword(user.password());
@ -62,8 +58,7 @@ void User::update(User const &user)
//****************************************************************************************************************************************************
/// \param[in] makeItActive Should split mode be made active.
//****************************************************************************************************************************************************
void User::toggleSplitMode(bool makeItActive)
{
void User::toggleSplitMode(bool makeItActive) {
emit toggleSplitModeForUser(id_, makeItActive);
}
@ -71,8 +66,7 @@ void User::toggleSplitMode(bool makeItActive)
//****************************************************************************************************************************************************
//
//****************************************************************************************************************************************************
void User::logout()
{
void User::logout() {
emit logoutUser(id_);
}
@ -80,8 +74,7 @@ void User::logout()
//****************************************************************************************************************************************************
//
//****************************************************************************************************************************************************
void User::remove()
{
void User::remove() {
emit removeUser(id_);
}
@ -89,8 +82,7 @@ void User::remove()
//****************************************************************************************************************************************************
/// \param[in] address The email address to configure Apple Mail for.
//****************************************************************************************************************************************************
void User::configureAppleMail(QString const &address)
{
void User::configureAppleMail(QString const &address) {
emit configureAppleMailForUser(id_, address);
}
@ -99,8 +91,7 @@ void User::configureAppleMail(QString const &address)
// The only purpose of this call is to forward to the QML application the toggleSplitModeFinished(userID) event
// that was received by the UserList model.
//****************************************************************************************************************************************************
void User::emitToggleSplitModeFinished()
{
void User::emitToggleSplitModeFinished() {
emit toggleSplitModeFinished();
}
@ -108,8 +99,7 @@ void User::emitToggleSplitModeFinished()
//****************************************************************************************************************************************************
/// \return The userID.
//****************************************************************************************************************************************************
QString User::id() const
{
QString User::id() const {
return id_;
}
@ -117,10 +107,10 @@ QString User::id() const
//****************************************************************************************************************************************************
/// \param[in] id The userID.
//****************************************************************************************************************************************************
void User::setID(QString const &id)
{
if (id == id_)
void User::setID(QString const &id) {
if (id == id_) {
return;
}
id_ = id;
emit idChanged(id_);
@ -130,8 +120,7 @@ void User::setID(QString const &id)
//****************************************************************************************************************************************************
/// \return The username.
//****************************************************************************************************************************************************
QString User::username() const
{
QString User::username() const {
return username_;
}
@ -139,10 +128,10 @@ QString User::username() const
//****************************************************************************************************************************************************
/// \param[in] username The username.
//****************************************************************************************************************************************************
void User::setUsername(QString const &username)
{
if (username == username_)
void User::setUsername(QString const &username) {
if (username == username_) {
return;
}
username_ = username;
emit usernameChanged(username_);
@ -152,8 +141,7 @@ void User::setUsername(QString const &username)
//****************************************************************************************************************************************************
/// \return The password.
//****************************************************************************************************************************************************
QString User::password() const
{
QString User::password() const {
return password_;
}
@ -161,10 +149,10 @@ QString User::password() const
//****************************************************************************************************************************************************
/// \param[in] password The password.
//****************************************************************************************************************************************************
void User::setPassword(QString const &password)
{
if (password == password_)
void User::setPassword(QString const &password) {
if (password == password_) {
return;
}
password_ = password;
emit passwordChanged(password_);
@ -174,8 +162,7 @@ void User::setPassword(QString const &password)
//****************************************************************************************************************************************************
/// \return The addresses.
//****************************************************************************************************************************************************
QStringList User::addresses() const
{
QStringList User::addresses() const {
return addresses_;
}
@ -183,10 +170,10 @@ QStringList User::addresses() const
//****************************************************************************************************************************************************
/// \param[in] addresses The addresses.
//****************************************************************************************************************************************************
void User::setAddresses(QStringList const &addresses)
{
if (addresses == addresses_)
void User::setAddresses(QStringList const &addresses) {
if (addresses == addresses_) {
return;
}
addresses_ = addresses;
emit addressesChanged(addresses_);
@ -196,8 +183,7 @@ void User::setAddresses(QStringList const &addresses)
//****************************************************************************************************************************************************
/// \return The avatar text.
//****************************************************************************************************************************************************
QString User::avatarText() const
{
QString User::avatarText() const {
return avatarText_;
}
@ -205,10 +191,10 @@ QString User::avatarText() const
//****************************************************************************************************************************************************
/// \param[in] avatarText The avatar text.
//****************************************************************************************************************************************************
void User::setAvatarText(QString const &avatarText)
{
if (avatarText == avatarText_)
void User::setAvatarText(QString const &avatarText) {
if (avatarText == avatarText_) {
return;
}
avatarText_ = avatarText;
emit usernameChanged(avatarText_);
@ -218,8 +204,7 @@ void User::setAvatarText(QString const &avatarText)
//****************************************************************************************************************************************************
/// \return The user state.
//****************************************************************************************************************************************************
UserState User::state() const
{
UserState User::state() const {
return state_;
}
@ -227,10 +212,10 @@ UserState User::state() const
//****************************************************************************************************************************************************
/// \param[in] state The user state.
//****************************************************************************************************************************************************
void User::setState(UserState state)
{
if (state_ == state)
void User::setState(UserState state) {
if (state_ == state) {
return;
}
state_ = state;
emit stateChanged(state);
@ -240,8 +225,7 @@ void User::setState(UserState state)
//****************************************************************************************************************************************************
/// \return The split mode status.
//****************************************************************************************************************************************************
bool User::splitMode() const
{
bool User::splitMode() const {
return splitMode_;
}
@ -249,10 +233,10 @@ bool User::splitMode() const
//****************************************************************************************************************************************************
/// \param[in] splitMode The split mode status.
//****************************************************************************************************************************************************
void User::setSplitMode(bool splitMode)
{
if (splitMode == splitMode_)
void User::setSplitMode(bool splitMode) {
if (splitMode == splitMode_) {
return;
}
splitMode_ = splitMode;
emit splitModeChanged(splitMode_);
@ -262,8 +246,7 @@ void User::setSplitMode(bool splitMode)
//****************************************************************************************************************************************************
/// \return The used bytes.
//****************************************************************************************************************************************************
float User::usedBytes() const
{
float User::usedBytes() const {
return usedBytes_;
}
@ -271,10 +254,10 @@ float User::usedBytes() const
//****************************************************************************************************************************************************
/// \param[in] usedBytes The used bytes.
//****************************************************************************************************************************************************
void User::setUsedBytes(float usedBytes)
{
if (usedBytes == usedBytes_)
void User::setUsedBytes(float usedBytes) {
if (usedBytes == usedBytes_) {
return;
}
usedBytes_ = usedBytes;
emit usedBytesChanged(usedBytes_);
@ -284,8 +267,7 @@ void User::setUsedBytes(float usedBytes)
//****************************************************************************************************************************************************
/// \return The total bytes.
//****************************************************************************************************************************************************
float User::totalBytes() const
{
float User::totalBytes() const {
return totalBytes_;
}
@ -293,10 +275,10 @@ float User::totalBytes() const
//****************************************************************************************************************************************************
/// \param[in] totalBytes The total bytes.
//****************************************************************************************************************************************************
void User::setTotalBytes(float totalBytes)
{
if (totalBytes == totalBytes_)
void User::setTotalBytes(float totalBytes) {
if (totalBytes == totalBytes_) {
return;
}
totalBytes_ = totalBytes;
emit totalBytesChanged(totalBytes_);
@ -307,13 +289,16 @@ void User::setTotalBytes(float totalBytes)
/// \param[in] state The user state.
/// \return A string describing the state.
//****************************************************************************************************************************************************
QString User::stateToString(UserState state)
{
QString User::stateToString(UserState state) {
switch (state) {
case UserState::SignedOut: return "Signed out";
case UserState::Locked: return "Locked";
case UserState::Connected: return "Connected";
default: return "Unknown";
case UserState::SignedOut:
return "Signed out";
case UserState::Locked:
return "Locked";
case UserState::Connected:
return "Connected";
default:
return "Unknown";
}
}

View File

@ -20,8 +20,7 @@
#define BRIDGE_PP_USER_H
namespace bridgepp
{
namespace bridgepp {
//****************************************************************************************************************************************************
@ -29,25 +28,25 @@ namespace bridgepp
/// See https://qml.guide/enums-in-qt-qml/ for details (we used Q_OBJECT instead of Q_GADGET as in the reference document avoid a QML warning
/// complaining about the case of the data type).
//****************************************************************************************************************************************************
class EUserState: public QObject
{
class EUserState : public QObject {
Q_OBJECT
public:
enum class State
{
enum class State {
SignedOut = 0,
Locked = 1,
Connected = 2
};
Q_ENUM(State)
EUserState() = delete; ///< Default constructor.
EUserState(EUserState const&) = delete; ///< Disabled copy-constructor.
EUserState(EUserState&&) = delete; ///< Disabled assignment copy-constructor.
EUserState(EUserState const &) = delete; ///< Disabled copy-constructor.
EUserState(EUserState &&) = delete; ///< Disabled assignment copy-constructor.
~EUserState() = default; ///< Destructor.
EUserState& operator=(EUserState const&) = delete; ///< Disabled assignment operator.
EUserState& operator=(EUserState&&) = delete; ///< Disabled move assignment operator.
EUserState &operator=(EUserState const &) = delete; ///< Disabled assignment operator.
EUserState &operator=(EUserState &&) = delete; ///< Disabled move assignment operator.
};
@ -60,8 +59,7 @@ typedef std::shared_ptr<class User> SPUser; ///< Type definition for shared poin
//****************************************************************************************************************************************************
/// \brief User class.
//****************************************************************************************************************************************************
class User : public QObject
{
class User : public QObject {
Q_OBJECT
public: // static member function

View File

@ -20,8 +20,7 @@
#include "../Exception/Exception.h"
namespace bridgepp
{
namespace bridgepp {
//****************************************************************************************************************************************************
@ -31,18 +30,17 @@ namespace bridgepp
Overseer::Overseer(Worker *worker, QObject *parent)
: QObject(parent)
, thread_(new QThread(parent))
, worker_(worker)
{
if (!worker_)
, worker_(worker) {
if (!worker_) {
throw Exception("Overseer cannot accept a nil worker.");
}
}
//****************************************************************************************************************************************************
//
//****************************************************************************************************************************************************
Overseer::~Overseer()
{
Overseer::~Overseer() {
this->releaseWorker();
}
@ -50,21 +48,21 @@ Overseer::~Overseer()
//****************************************************************************************************************************************************
/// \param[in] autorelease Should the overseer automatically release the worker and thread when done.
//****************************************************************************************************************************************************
void Overseer::startWorker(bool autorelease) const
{
if (!worker_)
void Overseer::startWorker(bool autorelease) const {
if (!worker_) {
throw Exception("Cannot start overseer with null worker.");
if (!thread_)
}
if (!thread_) {
throw Exception("Cannot start overseer with null thread.");
}
worker_->moveToThread(thread_);
connect(thread_, &QThread::started, worker_, &Worker::run);
connect(worker_, &Worker::finished, [&]() {thread_->quit(); }); // Safety, normally the thread already properly quits.
connect(worker_, &Worker::finished, [&]() { thread_->quit(); }); // Safety, normally the thread already properly quits.
connect(worker_, &Worker::error, [&]() { thread_->quit(); });
connect(worker_, &Worker::cancelled, [&]() { thread_->quit(); });
if (autorelease)
{
if (autorelease) {
connect(worker_, &Worker::error, this, &Overseer::releaseWorker);
connect(worker_, &Worker::cancelled, this, &Overseer::releaseWorker);
connect(worker_, &Worker::finished, this, &Overseer::releaseWorker);
@ -77,18 +75,14 @@ void Overseer::startWorker(bool autorelease) const
//****************************************************************************************************************************************************
//
//****************************************************************************************************************************************************
void Overseer::releaseWorker()
{
if (worker_)
{
void Overseer::releaseWorker() {
if (worker_) {
worker_->deleteLater();
worker_ = nullptr;
}
if (thread_)
{
if (!thread_->isFinished())
{
if (thread_) {
if (!thread_->isFinished()) {
thread_->quit();
thread_->wait();
}
@ -101,10 +95,10 @@ void Overseer::releaseWorker()
//****************************************************************************************************************************************************
/// \return true iff the worker is finished.
//****************************************************************************************************************************************************
bool Overseer::isFinished() const
{
if ((!worker_) || (!worker_->thread()))
bool Overseer::isFinished() const {
if ((!worker_) || (!worker_->thread())) {
return true;
}
return worker_->thread()->isFinished();
}
@ -115,17 +109,19 @@ bool Overseer::isFinished() const
/// never times out.
/// \return false if and only if the timeout delay was reached.
//****************************************************************************************************************************************************
bool Overseer::wait(qint32 timeoutMs) const
{
if (this->isFinished())
bool Overseer::wait(qint32 timeoutMs) const {
if (this->isFinished()) {
return true;
}
QEventLoop loop;
QTimer timer;
bool inTime = true;
if (timeoutMs >= 0)
{
connect(&timer, &QTimer::timeout, &loop, [&]() { loop.quit(); inTime = false; } );
if (timeoutMs >= 0) {
connect(&timer, &QTimer::timeout, &loop, [&]() {
loop.quit();
inTime = false;
});
timer.setSingleShot(true);
timer.start(timeoutMs);
}
@ -149,8 +145,7 @@ bool Overseer::wait(qint32 timeoutMs) const
//****************************************************************************************************************************************************
/// \return The worker.
//****************************************************************************************************************************************************
Worker *Overseer::worker() const
{
Worker *Overseer::worker() const {
return worker_;
}

View File

@ -23,15 +23,13 @@
#include "Worker.h"
namespace bridgepp
{
namespace bridgepp {
//****************************************************************************************************************************************************
/// \brief Overseer used to manager a worker instance and its associated thread.
//****************************************************************************************************************************************************
class Overseer : public QObject
{
class Overseer : public QObject {
Q_OBJECT
public: // member functions.
explicit Overseer(Worker *worker, QObject *parent); ///< Default constructor.
@ -49,8 +47,8 @@ public slots:
void releaseWorker(); ///< Delete the worker and its thread.
public: // data members.
QThread *thread_{nullptr}; ///< The thread.
Worker *worker_{nullptr}; ///< The worker.
QThread *thread_ { nullptr }; ///< The thread.
Worker *worker_ { nullptr }; ///< The worker.
};

View File

@ -20,20 +20,17 @@
#define BRIDGE_PP_WORKER_H
namespace bridgepp
{
namespace bridgepp {
//****************************************************************************************************************************************************
/// \brief Pure virtual class for worker intended to perform a threaded operation.
//****************************************************************************************************************************************************
class Worker : public QObject
{
class Worker : public QObject {
Q_OBJECT
public: // member functions
explicit Worker(QObject *parent)
: QObject(parent)
{} ///< Default constructor.
: QObject(parent) {} ///< Default constructor.
Worker(Worker const &) = delete; ///< Disabled copy-constructor.
Worker(Worker &&) = delete; ///< Disabled assignment copy-constructor.
~Worker() override = default; ///< Destructor.