diff --git a/scwx-qt/scwx-qt.cmake b/scwx-qt/scwx-qt.cmake index 087c61e5..a386d8b9 100644 --- a/scwx-qt/scwx-qt.cmake +++ b/scwx-qt/scwx-qt.cmake @@ -260,6 +260,7 @@ set(HDR_UI source/scwx/qt/ui/about_dialog.hpp source/scwx/qt/ui/edit_marker_dialog.hpp source/scwx/qt/ui/flow_layout.hpp source/scwx/qt/ui/gps_info_dialog.hpp + source/scwx/qt/ui/high_privilege_dialog.hpp source/scwx/qt/ui/hotkey_edit.hpp source/scwx/qt/ui/imgui_debug_dialog.hpp source/scwx/qt/ui/imgui_debug_widget.hpp @@ -291,6 +292,7 @@ set(SRC_UI source/scwx/qt/ui/about_dialog.cpp source/scwx/qt/ui/edit_marker_dialog.cpp source/scwx/qt/ui/flow_layout.cpp source/scwx/qt/ui/gps_info_dialog.cpp + source/scwx/qt/ui/high_privilege_dialog.cpp source/scwx/qt/ui/hotkey_edit.cpp source/scwx/qt/ui/imgui_debug_dialog.cpp source/scwx/qt/ui/imgui_debug_widget.cpp @@ -320,6 +322,7 @@ set(UI_UI source/scwx/qt/ui/about_dialog.ui source/scwx/qt/ui/edit_line_dialog.ui source/scwx/qt/ui/edit_marker_dialog.ui source/scwx/qt/ui/gps_info_dialog.ui + source/scwx/qt/ui/high_privilege_dialog.ui source/scwx/qt/ui/imgui_debug_dialog.ui source/scwx/qt/ui/layer_dialog.ui source/scwx/qt/ui/open_url_dialog.ui diff --git a/scwx-qt/source/scwx/qt/main/main.cpp b/scwx-qt/source/scwx/qt/main/main.cpp index e8a833b4..4a6445d0 100644 --- a/scwx-qt/source/scwx/qt/main/main.cpp +++ b/scwx-qt/source/scwx/qt/main/main.cpp @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -21,6 +22,7 @@ #include #include +#include #include #include @@ -32,8 +34,6 @@ #include #include -#include - #define QT6CT_LIBRARY #include #undef QT6CT_LIBRARY @@ -46,6 +46,9 @@ static void OverrideDefaultStyle(const std::vector& args); int main(int argc, char* argv[]) { + bool disableHighPrivilegeWarning = false; + bool highPrivilegeChecked = false; + // Store arguments std::vector args {}; for (int i = 0; i < argc; ++i) @@ -76,25 +79,35 @@ int main(int argc, char* argv[]) QCoreApplication::installTranslator(&translator); } - // Test to see if scwx was run with high privilege - if (scwx::qt::util::is_high_privilege()) - { - QMessageBox::StandardButton pressed = QMessageBox::warning( - nullptr, - "Warning: Running with High Privileges", - "Although Supercell-Wx can be run with high privileges, " - "it is not recommended", - QMessageBox::Ok | QMessageBox::Close); - if (pressed & QMessageBox::Ok) { - return 0; - } - } - if (!scwx::util::GetEnvironment("SCWX_TEST").empty()) { QStandardPaths::setTestModeEnabled(true); } + // Test to see if scwx was run with high privilege + std::string appDataPath { + QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + .toStdString()}; + + // Check if high privilege before writing settings, assuming no settings + // have been written + if (!std::filesystem::exists(appDataPath) && + scwx::qt::util::is_high_privilege()) + { + auto dialog = + scwx::qt::ui::HighPrivilegeDialog(); // TODO does this need cleaned up? + const int result = dialog.exec(); + + disableHighPrivilegeWarning = dialog.disable_high_privilege_message(); + highPrivilegeChecked = true; + + if (result == QDialog::Rejected) + { + // TODO any other cleanup needed here? + return 0; + } + } + // Start the io_context main loop boost::asio::io_context& ioContext = scwx::util::io_context(); auto work = boost::asio::make_work_guard(ioContext); @@ -133,6 +146,46 @@ int main(int argc, char* argv[]) // Check process modules for compatibility scwx::qt::main::CheckProcessModules(); + auto& generalSettings = scwx::qt::settings::GeneralSettings::Instance(); + + if (!highPrivilegeChecked && + generalSettings.high_privilege_warning_enabled().GetValue() && + scwx::qt::util::is_high_privilege()) + { + auto dialog = + scwx::qt::ui::HighPrivilegeDialog(); // TODO does this need cleaned up? + const int result = dialog.exec(); + + disableHighPrivilegeWarning = dialog.disable_high_privilege_message(); + + if (result == QDialog::Rejected) + { + // Deinitialize application + scwx::qt::manager::RadarProductManager::Cleanup(); + + // Stop Qt Threads + scwx::qt::manager::ThreadManager::Instance().StopThreads(); + + // Gracefully stop the io_context main loop + work.reset(); + threadPool.join(); + + // Shutdown application + scwx::qt::manager::ResourceManager::Shutdown(); + scwx::qt::manager::SettingsManager::Instance().Shutdown(); + + // Shutdown AWS SDK + Aws::ShutdownAPI(awsSdkOptions); + return 0; + } + } + + // Save high privilege settings + if (disableHighPrivilegeWarning) + { + generalSettings.high_privilege_warning_enabled().SetValue(false); + scwx::qt::manager::SettingsManager::Instance().SaveSettings(); + } // Run initial setup if required if (scwx::qt::ui::setup::SetupWizard::IsSetupRequired()) diff --git a/scwx-qt/source/scwx/qt/settings/general_settings.cpp b/scwx-qt/source/scwx/qt/settings/general_settings.cpp index 77ca764e..0abb45e9 100644 --- a/scwx-qt/source/scwx/qt/settings/general_settings.cpp +++ b/scwx-qt/source/scwx/qt/settings/general_settings.cpp @@ -80,6 +80,7 @@ public: warningsProvider_.SetDefault(defaultWarningsProviderValue); cursorIconAlwaysOn_.SetDefault(false); radarSiteThreshold_.SetDefault(0.0); + highPrivilegeWarningEnabled_.SetDefault(true); fontSizes_.SetElementMinimum(1); fontSizes_.SetElementMaximum(72); @@ -175,6 +176,8 @@ public: SettingsVariable warningsProvider_ {"warnings_provider"}; SettingsVariable cursorIconAlwaysOn_ {"cursor_icon_always_on"}; SettingsVariable radarSiteThreshold_ {"radar_site_threshold"}; + SettingsVariable highPrivilegeWarningEnabled_ { + "high_privilege_warning_enabled"}; }; GeneralSettings::GeneralSettings() : @@ -210,7 +213,8 @@ GeneralSettings::GeneralSettings() : &p->updateNotificationsEnabled_, &p->warningsProvider_, &p->cursorIconAlwaysOn_, - &p->radarSiteThreshold_}); + &p->radarSiteThreshold_, + &p->highPrivilegeWarningEnabled_}); SetDefaults(); } GeneralSettings::~GeneralSettings() = default; @@ -375,6 +379,11 @@ SettingsVariable& GeneralSettings::radar_site_threshold() const return p->radarSiteThreshold_; } +SettingsVariable& GeneralSettings::high_privilege_warning_enabled() const +{ + return p->highPrivilegeWarningEnabled_; +} + bool GeneralSettings::Shutdown() { bool dataChanged = false; @@ -429,7 +438,9 @@ bool operator==(const GeneralSettings& lhs, const GeneralSettings& rhs) rhs.p->updateNotificationsEnabled_ && lhs.p->warningsProvider_ == rhs.p->warningsProvider_ && lhs.p->cursorIconAlwaysOn_ == rhs.p->cursorIconAlwaysOn_ && - lhs.p->radarSiteThreshold_ == rhs.p->radarSiteThreshold_); + lhs.p->radarSiteThreshold_ == rhs.p->radarSiteThreshold_ && + lhs.p->highPrivilegeWarningEnabled_ == + rhs.p->highPrivilegeWarningEnabled_); } } // namespace settings diff --git a/scwx-qt/source/scwx/qt/settings/general_settings.hpp b/scwx-qt/source/scwx/qt/settings/general_settings.hpp index 6a49566b..074b956e 100644 --- a/scwx-qt/source/scwx/qt/settings/general_settings.hpp +++ b/scwx-qt/source/scwx/qt/settings/general_settings.hpp @@ -56,6 +56,7 @@ public: SettingsVariable& warnings_provider() const; SettingsVariable& cursor_icon_always_on() const; SettingsVariable& radar_site_threshold() const; + SettingsVariable& high_privilege_warning_enabled() const; static GeneralSettings& Instance(); diff --git a/scwx-qt/source/scwx/qt/ui/high_privilege_dialog.cpp b/scwx-qt/source/scwx/qt/ui/high_privilege_dialog.cpp new file mode 100644 index 00000000..0c60052a --- /dev/null +++ b/scwx-qt/source/scwx/qt/ui/high_privilege_dialog.cpp @@ -0,0 +1,47 @@ +#include "high_privilege_dialog.hpp" +#include "ui_high_privilege_dialog.h" + +#include +#include + +namespace scwx +{ +namespace qt +{ +namespace ui +{ + +static const std::string logPrefix_ = "scwx::qt::ui::high_privilege_dialog"; +static const auto logger_ = scwx::util::Logger::Create(logPrefix_); + +class HighPrivilegeDialogImpl +{ +public: + explicit HighPrivilegeDialogImpl(HighPrivilegeDialog* self) : + self_ {self} {}; + ~HighPrivilegeDialogImpl() = default; + + HighPrivilegeDialog* self_; +}; + +HighPrivilegeDialog::HighPrivilegeDialog(QWidget* parent) : + QDialog(parent), + p {std::make_unique(this)}, + ui(new Ui::HighPrivilegeDialog) +{ + ui->setupUi(this); +} + +bool HighPrivilegeDialog::disable_high_privilege_message() { + return ui->highPrivilegeCheckBox->isChecked(); +} + +HighPrivilegeDialog::~HighPrivilegeDialog() +{ + delete ui; +} + +} // namespace ui +} // namespace qt +} // namespace scwx + diff --git a/scwx-qt/source/scwx/qt/ui/high_privilege_dialog.hpp b/scwx-qt/source/scwx/qt/ui/high_privilege_dialog.hpp new file mode 100644 index 00000000..5271d245 --- /dev/null +++ b/scwx-qt/source/scwx/qt/ui/high_privilege_dialog.hpp @@ -0,0 +1,40 @@ +#pragma once + +#include + +namespace Ui +{ +class HighPrivilegeDialog; +} + +namespace scwx +{ +namespace qt +{ +namespace ui +{ + +class HighPrivilegeDialogImpl; + +class HighPrivilegeDialog : public QDialog +{ + Q_OBJECT + +private: + Q_DISABLE_COPY(HighPrivilegeDialog) + +public: + explicit HighPrivilegeDialog(QWidget* parent = nullptr); + ~HighPrivilegeDialog(); + + bool disable_high_privilege_message(); + +private: + friend HighPrivilegeDialogImpl; + std::unique_ptr p; + Ui::HighPrivilegeDialog* ui; +}; + +} // namespace ui +} // namespace qt +} // namespace scwx diff --git a/scwx-qt/source/scwx/qt/ui/high_privilege_dialog.ui b/scwx-qt/source/scwx/qt/ui/high_privilege_dialog.ui new file mode 100644 index 00000000..4d6f5075 --- /dev/null +++ b/scwx-qt/source/scwx/qt/ui/high_privilege_dialog.ui @@ -0,0 +1,101 @@ + + + HighPrivilegeDialog + + + + 0 + 0 + 301 + 269 + + + + + 0 + 0 + + + + Warning: High Privilege + + + + + + + 0 + 0 + + + + <html><head/><body><h1 align="center" style=" margin-top:18px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:xx-large; font-weight:700; color:#ff0000;">Warning: Run Supercell Wx with Low Privileges.</span></h1><p align="center">Please run Supercell Wx without admin or root permissions. Supercell Wx should not need such permissions to run. If you do not want to run Supercell Wx with high privilege, click &quot;Close&quot;, and relaunch with lower permissions. Otherwise, click &quot;Ignore&quot;. You may disable this warning with the checkbox below.</p></body></html> + + + Qt::TextFormat::RichText + + + Qt::AlignmentFlag::AlignLeading|Qt::AlignmentFlag::AlignLeft|Qt::AlignmentFlag::AlignTop + + + true + + + + + + + Disable High Privilege Warning + + + + + + + Qt::Orientation::Horizontal + + + QDialogButtonBox::StandardButton::Close|QDialogButtonBox::StandardButton::Ignore + + + + + + + + + + + buttonBox + accepted() + HighPrivilegeDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + HighPrivilegeDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + +