From fc12ebdd72c5f1524211333cd52fdd524ab954ba Mon Sep 17 00:00:00 2001 From: Nick Logozzo Date: Mon, 29 Jan 2024 16:22:34 -0500 Subject: [PATCH 01/10] Rename Nickvision::Aura module to Nickvision::App --- CMakeLists.txt | 10 ++++---- docs/README.md | 2 +- docs/{aura.md => app.md} | 24 ++++++++++++------- include/{aura => app}/appinfo.h | 2 +- include/{aura => app}/aura.h | 2 +- include/{aura => app}/configurationbase.h | 2 +- .../{aura => app}/interprocesscommunicator.h | 2 +- src/{aura => app}/appinfo.cpp | 4 ++-- src/{aura => app}/aura.cpp | 4 ++-- src/{aura => app}/configurationbase.cpp | 4 ++-- .../interprocesscommunicator.cpp | 6 ++--- src/filesystem/systemdirectories.cpp | 6 +++-- src/filesystem/userdirectories.cpp | 24 ++++++++++--------- src/localization/documentation.cpp | 12 ++++++---- src/localization/gettext.cpp | 8 ++++--- src/network/networkmonitor.cpp | 6 +++-- src/notifications/notifyicon.cpp | 6 +++-- src/notifications/shellnotification.cpp | 10 ++++---- src/update/updater.cpp | 5 ++-- tests/auratests.cpp | 4 ++-- tests/ipctests.cpp | 6 ++--- tests/networktests.cpp | 4 ++-- tests/notifyicontests.cpp | 4 ++-- 23 files changed, 90 insertions(+), 67 deletions(-) rename docs/{aura.md => app.md} (96%) rename include/{aura => app}/appinfo.h (99%) rename include/{aura => app}/aura.h (99%) rename include/{aura => app}/configurationbase.h (97%) rename include/{aura => app}/interprocesscommunicator.h (98%) rename src/{aura => app}/appinfo.cpp (98%) rename src/{aura => app}/aura.cpp (98%) rename src/{aura => app}/configurationbase.cpp (92%) rename src/{aura => app}/interprocesscommunicator.cpp (98%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0207e6e..5832824 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -20,7 +20,7 @@ endif() set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake") #libnick Definition -project ("libnick" LANGUAGES C CXX VERSION 2024.1.13 DESCRIPTION "A cross-platform base for native Nickvision applications.") +project ("libnick" LANGUAGES C CXX VERSION 2024.2.0 DESCRIPTION "A cross-platform base for native Nickvision applications.") include(CMakePackageConfigHelpers) include(GNUInstallDirs) include(CTest) @@ -31,10 +31,10 @@ if(LINUX) add_compile_definitions(HAVE_USLEEP) endif() add_library (${PROJECT_NAME} - "src/aura/appinfo.cpp" - "src/aura/aura.cpp" - "src/aura/configurationbase.cpp" - "src/aura/interprocesscommunicator.cpp" + "src/app/appinfo.cpp" + "src/app/aura.cpp" + "src/app/configurationbase.cpp" + "src/app/interprocesscommunicator.cpp" "src/filesystem/filesystemchangedeventargs.cpp" "src/filesystem/filesystemwatcher.cpp" "src/filesystem/systemdirectories.cpp" diff --git a/docs/README.md b/docs/README.md index ed90ae6..f8ead50 100644 --- a/docs/README.md +++ b/docs/README.md @@ -27,7 +27,7 @@ For example, assume a class has an event defined as `Nickvision::Events::Event& saved()`. ## Modules -- [Nickvision::Aura](aura.md) +- [Nickvision::App](app.md) - [Nickvision::Events](events.md) - [Nickvision::Filesystem](filesystem.md) - [Nickvision::Helpers](helpers.md) diff --git a/docs/aura.md b/docs/app.md similarity index 96% rename from docs/aura.md rename to docs/app.md index e7ecb90..b54f547 100644 --- a/docs/aura.md +++ b/docs/app.md @@ -15,7 +15,7 @@ Interface: [appinfo.h](/include/aura/appinfo.h) Type: `class` -Path: `Nickvision::Aura::AppInfo` +Path: `Nickvision::App::AppInfo` ### Member Variables - ``` @@ -131,11 +131,11 @@ Interface: [aura.h](/include/aura/aura.h) Type: `class` -Path: `Nickvision::Aura::Aura` +Path: `Nickvision::App::Aura` ### Member Variables - ``` - Nickvision::Aura::AppInfo& AppInfo: get + Nickvision::App::AppInfo& AppInfo: get ``` - The AppInfo object for the application - ``` @@ -203,7 +203,7 @@ Interface: [configurationbase.h](/include/aura/configurationbase.h) Type: `class` -Path: `Nickvision::Aura::ConfigurationBase` +Path: `Nickvision::App::ConfigurationBase` ### Member Variables - ``` @@ -242,10 +242,13 @@ Here are some key points when defining your own configuration objects: Here is an example of a custom configuration object using `ConfigurationBase`: ```cpp +using namespace Nickvision::App; + class AppConfig : public ConfigurationBase { public: - AppConfig(const std::string& key) : ConfigurationBase{ key } + AppConfig(const std::string& key) + : ConfigurationBase{ key } { } @@ -264,11 +267,14 @@ public: ``` This object can now be used by an Aura-based application: ```cpp +using namespace Nickvision::App; +using namespace Nickvision::Events; + int main() { Aura::getActive().init(...); AppConfig& config{ Aura::getActive().getConfig("config") }; - config.saved() += [](const Nickvision::Events::EventArgs& e) { std::cout << "Config saved to disk." << std::endl; }; + config.saved() += [](const EventArgs& e) { std::cout << "Config saved to disk." << std::endl; }; if(config.getPreviousCount() > 0) { std::cout << config.getPreviousCount() << std::endl; @@ -301,7 +307,7 @@ Interface: [interprocesscommunicator.h](/include/aura/interprocesscommunicator.h Type: `class` -Path: `Nickvision::Aura::InterProcessCommunicator` +Path: `Nickvision::App::InterProcessCommunicator` ### Member Variables - ``` @@ -351,9 +357,11 @@ Let's consider an example scenario for using the `InterProcessCommunicator`. Ass Here's the code for this: ```cpp +using namespace Nickvision::App; + int main(int argc, char*[] argv) { - Aura::getActive().init(...); //ensures AppInfo::id + Aura::getActive().init(...); std::vector modernArgs; for(int i = 0; i < argc; i++) { diff --git a/include/aura/appinfo.h b/include/app/appinfo.h similarity index 99% rename from include/aura/appinfo.h rename to include/app/appinfo.h index 25f1f9c..1ca113b 100644 --- a/include/aura/appinfo.h +++ b/include/app/appinfo.h @@ -6,7 +6,7 @@ #include #include "update/version.h" -namespace Nickvision::Aura +namespace Nickvision::App { /** * @brief A model for the information about an application. diff --git a/include/aura/aura.h b/include/app/aura.h similarity index 99% rename from include/aura/aura.h rename to include/app/aura.h index 54b7349..bd28593 100644 --- a/include/aura/aura.h +++ b/include/app/aura.h @@ -14,7 +14,7 @@ #include "appinfo.h" #include "configurationbase.h" -namespace Nickvision::Aura +namespace Nickvision::App { template concept DerivedConfigurationBase = std::is_base_of_v; diff --git a/include/aura/configurationbase.h b/include/app/configurationbase.h similarity index 97% rename from include/aura/configurationbase.h rename to include/app/configurationbase.h index 03a4f9a..4ecb762 100644 --- a/include/aura/configurationbase.h +++ b/include/app/configurationbase.h @@ -6,7 +6,7 @@ #include #include "events/event.h" -namespace Nickvision::Aura +namespace Nickvision::App { /** * A base class for configuration files. diff --git a/include/aura/interprocesscommunicator.h b/include/app/interprocesscommunicator.h similarity index 98% rename from include/aura/interprocesscommunicator.h rename to include/app/interprocesscommunicator.h index cf804c3..4f28390 100644 --- a/include/aura/interprocesscommunicator.h +++ b/include/app/interprocesscommunicator.h @@ -12,7 +12,7 @@ #include #endif -namespace Nickvision::Aura +namespace Nickvision::App { /** * @brief An inter process communicator (server/client). diff --git a/src/aura/appinfo.cpp b/src/app/appinfo.cpp similarity index 98% rename from src/aura/appinfo.cpp rename to src/app/appinfo.cpp index 07b7c57..9705884 100644 --- a/src/aura/appinfo.cpp +++ b/src/app/appinfo.cpp @@ -1,11 +1,11 @@ -#include "aura/appinfo.h" +#include "app/appinfo.h" #include #include #include "helpers/stringhelpers.h" using namespace Nickvision::Update; -namespace Nickvision::Aura +namespace Nickvision::App { const std::string& AppInfo::getId() const { diff --git a/src/aura/aura.cpp b/src/app/aura.cpp similarity index 98% rename from src/aura/aura.cpp rename to src/app/aura.cpp index 3c1a4e7..278617c 100644 --- a/src/aura/aura.cpp +++ b/src/app/aura.cpp @@ -1,4 +1,4 @@ -#include "aura/aura.h" +#include "app/aura.h" #include #include #include "filesystem/systemdirectories.h" @@ -12,7 +12,7 @@ using namespace Nickvision::Filesystem; -namespace Nickvision::Aura +namespace Nickvision::App { Aura::Aura() : m_initialized{ false } diff --git a/src/aura/configurationbase.cpp b/src/app/configurationbase.cpp similarity index 92% rename from src/aura/configurationbase.cpp rename to src/app/configurationbase.cpp index 291f85f..fcb1dc0 100644 --- a/src/aura/configurationbase.cpp +++ b/src/app/configurationbase.cpp @@ -1,11 +1,11 @@ -#include "aura/configurationbase.h" +#include "app/configurationbase.h" #include #include #include "filesystem/userdirectories.h" using namespace Nickvision::Filesystem; -namespace Nickvision::Aura +namespace Nickvision::App { ConfigurationBase::ConfigurationBase(const std::string& key) : m_key{ key } diff --git a/src/aura/interprocesscommunicator.cpp b/src/app/interprocesscommunicator.cpp similarity index 98% rename from src/aura/interprocesscommunicator.cpp rename to src/app/interprocesscommunicator.cpp index 290b86a..5477a4d 100644 --- a/src/aura/interprocesscommunicator.cpp +++ b/src/app/interprocesscommunicator.cpp @@ -1,13 +1,13 @@ -#include "aura/interprocesscommunicator.h" +#include "app/interprocesscommunicator.h" #include #include -#include "aura/aura.h" +#include "app/aura.h" #ifdef __linux__ #include #include #endif -namespace Nickvision::Aura +namespace Nickvision::App { InterProcessCommunicator::InterProcessCommunicator() : m_serverRunning{ false } diff --git a/src/filesystem/systemdirectories.cpp b/src/filesystem/systemdirectories.cpp index 95293fa..6c7ebb0 100644 --- a/src/filesystem/systemdirectories.cpp +++ b/src/filesystem/systemdirectories.cpp @@ -1,12 +1,14 @@ #include "filesystem/systemdirectories.h" -#include "aura/aura.h" +#include "app/aura.h" #include "helpers/stringhelpers.h" +using namespace Nickvision::App; + namespace Nickvision::Filesystem { static std::vector getFromVar(const std::string& var) { - std::string env{ Aura::Aura::getActive().getEnvVar(var) }; + std::string env{ Aura::getActive().getEnvVar(var) }; if (!env.empty()) { #ifdef _WIN32 diff --git a/src/filesystem/userdirectories.cpp b/src/filesystem/userdirectories.cpp index 46c3d38..8e7645e 100644 --- a/src/filesystem/userdirectories.cpp +++ b/src/filesystem/userdirectories.cpp @@ -1,7 +1,7 @@ #include "filesystem/userdirectories.h" #include #include -#include "aura/aura.h" +#include "app/aura.h" #include "helpers/stringhelpers.h" #ifdef _WIN32 #include @@ -12,12 +12,14 @@ #include #endif +using namespace Nickvision::App; + namespace Nickvision::Filesystem { #ifdef __linux__ static std::filesystem::path getXDGDir(const std::string& key) { - std::string var{ Aura::Aura::getActive().getEnvVar(key) }; + std::string var{ Aura::getActive().getEnvVar(key) }; if (!var.empty()) { return var; @@ -60,7 +62,7 @@ namespace Nickvision::Filesystem } CoTaskMemFree(static_cast(p)); #elif defined(__linux__) - std::filesystem::path var{ Aura::Aura::getActive().getEnvVar("HOME") }; + std::filesystem::path var{ Aura::getActive().getEnvVar("HOME") }; result = !var.empty() ? var : getpwuid(getuid())->pw_dir; #endif return result; @@ -77,7 +79,7 @@ namespace Nickvision::Filesystem } CoTaskMemFree(static_cast(p)); #elif defined(__linux__) - std::filesystem::path var{ Aura::Aura::getActive().getEnvVar("XDG_CONFIG_HOME") }; + std::filesystem::path var{ Aura::getActive().getEnvVar("XDG_CONFIG_HOME") }; result = !var.empty() ? var : (getHome() / ".config"); #endif std::filesystem::create_directories(result); @@ -86,7 +88,7 @@ namespace Nickvision::Filesystem std::filesystem::path UserDirectories::getApplicationConfig() { - std::filesystem::path result = getConfig() / Aura::Aura::getActive().getAppInfo().getName(); + std::filesystem::path result = getConfig() / Aura::getActive().getAppInfo().getName(); std::filesystem::create_directories(result); return result; } @@ -102,7 +104,7 @@ namespace Nickvision::Filesystem } CoTaskMemFree(static_cast(p)); #elif defined(__linux__) - std::filesystem::path var{ Aura::Aura::getActive().getEnvVar("XDG_CACHE_HOME") }; + std::filesystem::path var{ Aura::getActive().getEnvVar("XDG_CACHE_HOME") }; result = !var.empty() ? var : (getHome() / ".cache"); #endif std::filesystem::create_directories(result); @@ -111,7 +113,7 @@ namespace Nickvision::Filesystem std::filesystem::path UserDirectories::getApplicationCache() { - std::filesystem::path result = getCache() / Aura::Aura::getActive().getAppInfo().getName(); + std::filesystem::path result = getCache() / Aura::getActive().getAppInfo().getName(); std::filesystem::create_directories(result); return result; } @@ -122,7 +124,7 @@ namespace Nickvision::Filesystem #ifdef _WIN32 result = getConfig(); #elif defined(__linux__) - std::filesystem::path var{ Aura::Aura::getActive().getEnvVar("XDG_DATA_HOME") }; + std::filesystem::path var{ Aura::getActive().getEnvVar("XDG_DATA_HOME") }; result = !var.empty() ? var : (getHome() / ".local/share"); #endif std::filesystem::create_directories(result); @@ -131,7 +133,7 @@ namespace Nickvision::Filesystem std::filesystem::path UserDirectories::getApplicationLocalData() { - std::filesystem::path result{ getLocalData() / Aura::Aura::getActive().getAppInfo().getName() }; + std::filesystem::path result{ getLocalData() / Aura::getActive().getAppInfo().getName() }; std::filesystem::create_directories(result); return result; } @@ -140,8 +142,8 @@ namespace Nickvision::Filesystem { std::filesystem::path result; #ifdef __linux__ - std::filesystem::path var{ Aura::Aura::getActive().getEnvVar("XDG_RUNTIME_DIR") }; - result = !var.empty() ? var : (std::filesystem::path("/run/user/") / Aura::Aura::getActive().getEnvVar("UID")); + std::filesystem::path var{ Aura::getActive().getEnvVar("XDG_RUNTIME_DIR") }; + result = !var.empty() ? var : (std::filesystem::path("/run/user/") / Aura::getActive().getEnvVar("UID")); #endif return result; } diff --git a/src/localization/documentation.cpp b/src/localization/documentation.cpp index aeef192..d46d7d6 100644 --- a/src/localization/documentation.cpp +++ b/src/localization/documentation.cpp @@ -1,17 +1,19 @@ #include "localization/documentation.h" #include -#include "aura/aura.h" +#include "app/aura.h" #include "helpers/stringhelpers.h" #include "localization/gettext.h" +using namespace Nickvision::App; + namespace Nickvision::Localization { std::string Documentation::getHelpUrl(const std::string& pageName) { #ifdef __linux__ - if (Aura::Aura::getActive().getEnvVar("SNAP").empty()) + if (Aura::getActive().getEnvVar("SNAP").empty()) { - return "help:" + StringHelpers::toLower(Aura::Aura::getActive().getAppInfo().getEnglishShortName()) + "/" + pageName; + return "help:" + StringHelpers::toLower(Aura::getActive().getAppInfo().getEnglishShortName()) + "/" + pageName; } #endif std::string lang{ "C" }; @@ -25,7 +27,7 @@ namespace Nickvision::Localization * language code) to the list of available translated languages for the app. */ std::vector langs; - for (const std::filesystem::directory_entry& e : std::filesystem::directory_iterator(Aura::Aura::getActive().getExecutableDirectory())) + for (const std::filesystem::directory_entry& e : std::filesystem::directory_iterator(Aura::getActive().getExecutableDirectory())) { if (e.is_directory() && std::filesystem::exists(e.path() / (Gettext::getDomainName() + ".mo"))) { @@ -49,6 +51,6 @@ namespace Nickvision::Localization } } } - return "https://htmlpreview.github.io/?" + Aura::Aura::getActive().getAppInfo().getHtmlDocsStore() + "/" + lang + "/" + pageName + ".html"; + return "https://htmlpreview.github.io/?" + Aura::getActive().getAppInfo().getHtmlDocsStore() + "/" + lang + "/" + pageName + ".html"; } } \ No newline at end of file diff --git a/src/localization/gettext.cpp b/src/localization/gettext.cpp index 2f41a05..00fc3b0 100644 --- a/src/localization/gettext.cpp +++ b/src/localization/gettext.cpp @@ -1,7 +1,9 @@ #include "localization/gettext.h" #include #include -#include "aura/aura.h" +#include "app/aura.h" + +using namespace Nickvision::App; namespace Nickvision::Localization { @@ -16,9 +18,9 @@ namespace Nickvision::Localization setlocale(LC_ALL, ""); m_domainName = domainName; #ifdef _WIN32 - res = res && (wbindtextdomain(m_domainName.c_str(), Aura::Aura::getActive().getExecutableDirectory().c_str()) != nullptr); + res = res && (wbindtextdomain(m_domainName.c_str(), Aura::getActive().getExecutableDirectory().c_str()) != nullptr); #elif defined(__linux__) - res = res && (bindtextdomain(m_domainName.c_str(), Aura::Aura::getActive().getExecutableDirectory().c_str()) != nullptr); + res = res && (bindtextdomain(m_domainName.c_str(), Aura::getActive().getExecutableDirectory().c_str()) != nullptr); res = res && (bind_textdomain_codeset(m_domainName.c_str(), "UTF-8") != nullptr); #endif res = res && (textdomain(m_domainName.c_str()) != nullptr); diff --git a/src/network/networkmonitor.cpp b/src/network/networkmonitor.cpp index dd6c599..914c57a 100644 --- a/src/network/networkmonitor.cpp +++ b/src/network/networkmonitor.cpp @@ -1,11 +1,13 @@ #include "network/networkmonitor.h" #include -#include "aura/aura.h" +#include "app/aura.h" #include "helpers/stringhelpers.h" #ifdef __linux__ #include #endif +using namespace Nickvision::App; + namespace Nickvision::Network { #ifdef _WIN32 @@ -124,7 +126,7 @@ namespace Nickvision::Network { std::lock_guard lock{ m_mutex }; NetworkState newState{ NetworkState::Disconnected }; - std::string noNetCheck{ StringHelpers::toLower(Aura::Aura::getActive().getEnvVar("AURA_DISABLE_NETCHECK")) }; + std::string noNetCheck{ StringHelpers::toLower(Aura::getActive().getEnvVar("AURA_DISABLE_NETCHECK")) }; if (!noNetCheck.empty() && (noNetCheck == "true" || noNetCheck == "t" || noNetCheck == "yes" || noNetCheck == "y" || noNetCheck == "1")) { newState = NetworkState::ConnectedGlobal; diff --git a/src/notifications/notifyicon.cpp b/src/notifications/notifyicon.cpp index 148335e..61739ec 100644 --- a/src/notifications/notifyicon.cpp +++ b/src/notifications/notifyicon.cpp @@ -2,9 +2,11 @@ #include "notifications/notifyicon.h" #include #include -#include "aura/aura.h" +#include "app/aura.h" #include "helpers/stringhelpers.h" +using namespace Nickvision::App; + namespace Nickvision::Notifications { std::map NotifyIcon::m_icons = {}; @@ -12,7 +14,7 @@ namespace Nickvision::Notifications NotifyIcon::NotifyIcon(HWND hwnd, const NotifyIconMenu& contextMenu, bool hidden) : m_className{ StringHelpers::newGuid() }, m_isHidden{ hidden }, - m_tooltip{ Aura::Aura::getActive().getAppInfo().getName() }, + m_tooltip{ Aura::getActive().getAppInfo().getName() }, m_contextMenu{ contextMenu }, m_hwnd{ nullptr } { diff --git a/src/notifications/shellnotification.cpp b/src/notifications/shellnotification.cpp index 7a23df7..0d573a4 100644 --- a/src/notifications/shellnotification.cpp +++ b/src/notifications/shellnotification.cpp @@ -2,7 +2,7 @@ #include #include #include -#include "aura/aura.h" +#include "app/aura.h" #ifdef _WIN32 #include "notifications/notifyicon.h" #include "notifications/notifyiconmenu.h" @@ -10,6 +10,8 @@ #include #endif +using namespace Nickvision::App; + namespace Nickvision::Notifications { #ifdef _WIN32 @@ -27,15 +29,15 @@ namespace Nickvision::Notifications GNotification* notification{ g_notification_new(e.getTitle().c_str()) }; GIcon* icon{ nullptr }; GFile* fileIcon{ nullptr }; - std::string appId{ Aura::Aura::getActive().getAppInfo().getId() }; - if (Aura::Aura::getActive().getEnvVar("SNAP").empty()) + std::string appId{ Aura::getActive().getAppInfo().getId() }; + if (Aura::getActive().getEnvVar("SNAP").empty()) { std::string name{ appId + "-symbolic" }; icon = g_themed_icon_new(name.c_str()); } else { - std::string path{ Aura::Aura::getActive().getEnvVar("SNAP") + "/usr/share/icons/hicolor/symbolic/apps/" + appId + "-symbolic.svg"}; + std::string path{ Aura::getActive().getEnvVar("SNAP") + "/usr/share/icons/hicolor/symbolic/apps/" + appId + "-symbolic.svg"}; fileIcon = g_file_new_for_path(path.c_str()); icon = g_file_icon_new(fileIcon); } diff --git a/src/update/updater.cpp b/src/update/updater.cpp index f60a784..f8fb0f3 100644 --- a/src/update/updater.cpp +++ b/src/update/updater.cpp @@ -4,7 +4,7 @@ #include #include #include -#include "aura/aura.h" +#include "app/aura.h" #include "filesystem/userdirectories.h" #include "helpers/stringhelpers.h" #include "helpers/webhelpers.h" @@ -12,6 +12,7 @@ #include #endif +using namespace Nickvision::App; using namespace Nickvision::Filesystem; namespace Nickvision::Update @@ -22,7 +23,7 @@ namespace Nickvision::Update { if (!WebHelpers::isValidWebsite(githubRepoUrl)) { - githubRepoUrl = Aura::Aura::getActive().getAppInfo().getSourceRepo(); + githubRepoUrl = Aura::getActive().getAppInfo().getSourceRepo(); if (!WebHelpers::isValidWebsite(githubRepoUrl)) { throw std::invalid_argument("The source repo of the active Aura::AppInfo is invalid."); diff --git a/tests/auratests.cpp b/tests/auratests.cpp index 74564f0..801f3e8 100644 --- a/tests/auratests.cpp +++ b/tests/auratests.cpp @@ -1,9 +1,9 @@ #include -#include "aura/aura.h" +#include "app/aura.h" #include "filesystem/userdirectories.h" #include "notifications/shellnotification.h" -using namespace Nickvision::Aura; +using namespace Nickvision::App; using namespace Nickvision::Filesystem; using namespace Nickvision::Notifications; diff --git a/tests/ipctests.cpp b/tests/ipctests.cpp index e3fd1f0..9413df1 100644 --- a/tests/ipctests.cpp +++ b/tests/ipctests.cpp @@ -1,9 +1,9 @@ #include #include -#include "aura/aura.h" -#include "aura/interprocesscommunicator.h" +#include "app/aura.h" +#include "app/interprocesscommunicator.h" -using namespace Nickvision::Aura; +using namespace Nickvision::App; using namespace Nickvision::Events; static std::vector args{ "test1", "test2" }; diff --git a/tests/networktests.cpp b/tests/networktests.cpp index 351fa67..ce5ed4e 100644 --- a/tests/networktests.cpp +++ b/tests/networktests.cpp @@ -1,8 +1,8 @@ #include -#include "aura/aura.h" +#include "app/aura.h" #include "network/networkmonitor.h" -using namespace Nickvision::Aura; +using namespace Nickvision::App; using namespace Nickvision::Network; TEST(NetworkTests, ConnectedGlobal) diff --git a/tests/notifyicontests.cpp b/tests/notifyicontests.cpp index 41ef7ee..20ba725 100644 --- a/tests/notifyicontests.cpp +++ b/tests/notifyicontests.cpp @@ -2,11 +2,11 @@ #include #include #include -#include "aura/aura.h" +#include "app/aura.h" #include "notifications/notifyicon.h" #include "notifications/notifyiconmenu.h" -using namespace Nickvision::Aura; +using namespace Nickvision::App; using namespace Nickvision::Notifications; class NotifyIconTest : public testing::Test From 8e414d064d7422265600dc81d53e8fe2cb19280c Mon Sep 17 00:00:00 2001 From: Nick Logozzo Date: Mon, 29 Jan 2024 16:44:05 -0500 Subject: [PATCH 02/10] App - Better InterProcessCommunicator API - The InterProcessCommunicator constructor now accepts the id to use for the named pipe. - For an application-wide IPC, get the InterProcessCommunicator object with `Aura::getActive().getIPC()` --- docs/app.md | 7 +- include/app/aura.h | 167 +++++++------- include/app/interprocesscommunicator.h | 107 ++++----- src/app/aura.cpp | 175 +++++++------- src/app/interprocesscommunicator.cpp | 307 ++++++++++++------------- tests/ipctests.cpp | 15 +- 6 files changed, 393 insertions(+), 385 deletions(-) diff --git a/docs/app.md b/docs/app.md index b54f547..e3cfec1 100644 --- a/docs/app.md +++ b/docs/app.md @@ -328,10 +328,11 @@ Path: `Nickvision::App::InterProcessCommunicator` ### Methods - ```cpp - InterProcessCommunicator() + InterProcessCommunicator(const std::string& id) ``` - Constructs an InterProcessCommunicator. - - Note: If this is the first IPC instance for all processes of this AppInfo::id, this instance will become an IPC server. + - Accepts: The id of the ipc, id. id should be the same value for all instances of ipc that must talk to each other. + - Note: If this is the first IPC instance for all processes of id, this instance will become an IPC server. - Note: If this is not the first IPC instance, this instance will become an IPC client. - Throws: `std::runtime_error` if the client or server IPC cannot be created. - ```cpp @@ -370,7 +371,7 @@ int main(int argc, char*[] argv) modernArgs.push_back({ argv[i] }); } } - InterProcessCommunicator ipc; + InterProcessCommunicator& ipc{ Aura::getActuve().getIPC() }; ipc.commandReceived() += [](const Events::ParamEventArgs>& args) { ... }; ipc.communicate(modernArgs, true); } diff --git a/include/app/aura.h b/include/app/aura.h index bd28593..68a630c 100644 --- a/include/app/aura.h +++ b/include/app/aura.h @@ -13,104 +13,111 @@ #include #include "appinfo.h" #include "configurationbase.h" +#include "interprocesscommunicator.h" namespace Nickvision::App { - template - concept DerivedConfigurationBase = std::is_base_of_v; + template + concept DerivedConfigurationBase = std::is_base_of_v; - /** - * @brief An application base. - */ - class Aura - { - public: + /** + * @brief An application base. + */ + class Aura + { + public: Aura(const Aura&) = delete; void operator=(const Aura&) = delete; - /** - * @brief Destructs an Aura. - */ - ~Aura(); /** - * @brief Initializes Aura. - * @brief This also calls curl_global_init(). - * @brief This also calls Localization::Gettext::init(). - * @param id The application id - * @param name The application name - * @param englishShortName The application short name in English - * @throw std::runtime_error Thrown if libcurl fails to initialize - * @throw std::runtime_error Thrown if the gettext system fails to initialize + * @brief Destructs an Aura. + */ + ~Aura(); + /** + * @brief Initializes Aura. + * @brief This also calls curl_global_init(). + * @brief This also calls Localization::Gettext::init(). + * @param id The application id + * @param name The application name + * @param englishShortName The application short name in English * @throw std::runtime_error Thrown if unable to get the executable directory path + * @throw std::runtime_error Thrown if libcurl fails to initialize + * @throw std::runtime_error Thrown if the gettext system fails to initialize * @return True if initialized, else false - */ + */ bool init(const std::string& id, const std::string& name, const std::string& englishShortName); - /** - * @brief Gets the AppInfo object for the application. - */ - AppInfo& getAppInfo(); /** - * @brief Gets the path of the executable's directory. - * @return The executable's directory path - */ - const std::filesystem::path& getExecutableDirectory() const; - /** - * @brief Gets a system environment variable. - * @param key The environment variable to get - * @return The environment variable if found, else empty string - */ - std::string getEnvVar(const std::string& key); - /** - * @brief Sets a system environment variable. - * @param key The environment variable to set - * @param value The value for the environment variable - * @return True if set, else false - */ - bool setEnvVar(const std::string& key, const std::string& value); - /** - * @brief Finds the path of a given dependency. - * @param dependency The name of the dependency to find - * @return The path of the dependency if found, else empty path - */ - const std::filesystem::path& findDependency(std::string dependency); + * @brief Gets the path of the executable's directory. + * @return The executable's directory path + */ + const std::filesystem::path& getExecutableDirectory() const; + /** + * @brief Gets the AppInfo object for the application. + */ + AppInfo& getAppInfo(); + /** + * @brief Gets the application's InterProcessCommunicator object. + * @return The InterProcessCommunicator + */ + InterProcessCommunicator& getIPC(); + /** + * @brief Gets a system environment variable. + * @param key The environment variable to get + * @return The environment variable if found, else empty string + */ + std::string getEnvVar(const std::string& key); /** - * @brief Gets a config object. - * @tparam T Derived type of ConfigurationBase - * @param key The key of the config file - * @throw std::invalid_argument Thrown if key is empty - * @return The config object - */ - template - T& getConfig(const std::string& key) - { - if (key.empty()) - { - throw std::invalid_argument("Key must not be empty."); - } - if (!m_configFiles.contains(key)) - { - m_configFiles[key] = std::make_unique(key); - } - return *static_cast(m_configFiles[key].get()); - } + * @brief Sets a system environment variable. + * @param key The environment variable to set + * @param value The value for the environment variable + * @return True if set, else false + */ + bool setEnvVar(const std::string& key, const std::string& value); + /** + * @brief Finds the path of a given dependency. + * @param dependency The name of the dependency to find + * @return The path of the dependency if found, else empty path + */ + const std::filesystem::path& findDependency(std::string dependency); + /** + * @brief Gets a config object. + * @tparam T Derived type of ConfigurationBase + * @param key The key of the config file + * @throw std::invalid_argument Thrown if key is empty + * @return The config object + */ + template + T& getConfig(const std::string& key) + { + if (key.empty()) + { + throw std::invalid_argument("Key must not be empty."); + } + if (!m_configFiles.contains(key)) + { + m_configFiles[key] = std::make_unique(key); + } + return *static_cast(m_configFiles[key].get()); + } - private: - /** - * @brief Constructs an Aura. - */ - Aura(); + private: + /** + * @brief Constructs an Aura. + */ + Aura(); bool m_initialized; - AppInfo m_appInfo; std::filesystem::path m_executableDirectory; + AppInfo m_appInfo; + std::unique_ptr m_ipc; std::map m_dependencies; std::map> m_configFiles; - public: - /** - * @brief Gets the active aura instance. - * @return The active aura instance - */ - static Aura& getActive(); - }; + public: + /** + * @brief Gets the active aura instance. + * @return The active aura instance + */ + static Aura& getActive(); + }; } #endif //AURA_H \ No newline at end of file diff --git a/include/app/interprocesscommunicator.h b/include/app/interprocesscommunicator.h index 4f28390..91061c8 100644 --- a/include/app/interprocesscommunicator.h +++ b/include/app/interprocesscommunicator.h @@ -14,63 +14,64 @@ namespace Nickvision::App { - /** - * @brief An inter process communicator (server/client). - */ - class InterProcessCommunicator - { - public: - /** - * @brief Constructs an InterProcessCommunicator. - * @brief If this is the first IPC instance for all processes, this instance will become an IPC server. Else, this instance will become an IPC client. - * @throw std::runtime_error Thrown if the client or server IPC cannot be created - */ - InterProcessCommunicator(); - /** - * @brief Destructs an InterProcessCommunicator. - */ - ~InterProcessCommunicator(); - /** - * @brief Gets the event for when a command is received. - * @brief This event is only triggered on IPC server instances. - * @return The command received event - */ - Events::Event>>& commandReceived(); - /** - * @brief Gets whether or not this instance is an IPC server. - * @return True if this instance is an IPC server, else false. - */ - bool isServer() const; - /** - * @brief Gets whether or not this instance is an IPC client. - * @return True if this instance is an IPC client, else false. - */ - bool isClient() const; - /** - * @brief Communicates to the IPC server instance. - * @brief If this instance is the running server, commandReceived will be triggered with the passed arguments. - * @param args The command-line arguments - * @param exitIfClient Whether or not to exit this process if it is an IPC client - * @return True if command-line arguments were sent to a server instance - */ - bool communicate(const std::vector& args, bool exitIfClient = false); + /** + * @brief An inter process communicator (server/client). + */ + class InterProcessCommunicator + { + public: + /** + * @brief Constructs an InterProcessCommunicator. + * @brief If this is the first IPC instance for all processes, this instance will become an IPC server. Else, this instance will become an IPC client. + * @param id The id of the process (Must be the same amongst all IPCs that must talk to each other) + * @throw std::runtime_error Thrown if the client or server IPC cannot be created + */ + InterProcessCommunicator(const std::string& id); + /** + * @brief Destructs an InterProcessCommunicator. + */ + ~InterProcessCommunicator(); + /** + * @brief Gets the event for when a command is received. + * @brief This event is only triggered on IPC server instances. + * @return The command received event + */ + Events::Event>>& commandReceived(); + /** + * @brief Gets whether or not this instance is an IPC server. + * @return True if this instance is an IPC server, else false. + */ + bool isServer() const; + /** + * @brief Gets whether or not this instance is an IPC client. + * @return True if this instance is an IPC client, else false. + */ + bool isClient() const; + /** + * @brief Communicates to the IPC server instance. + * @brief If this instance is the running server, commandReceived will be triggered with the passed arguments. + * @param args The command-line arguments + * @param exitIfClient Whether or not to exit this process if it is an IPC client + * @return True if command-line arguments were sent to a server instance + */ + bool communicate(const std::vector& args, bool exitIfClient = false); - private: - /** - * @brief Runs the IPC server loop. - */ - void runServer(); - bool m_serverRunning; - Events::Event>> m_commandReceived; - std::jthread m_server; - std::string m_path; + private: + /** + * @brief Runs the IPC server loop. + */ + void runServer(); + bool m_serverRunning; + Events::Event>> m_commandReceived; + std::jthread m_server; + std::string m_path; #ifdef _WIN32 - HANDLE m_serverPipe; + HANDLE m_serverPipe; #elif defined(__linux__) - struct sockaddr_un m_sockaddr; - int m_serverSocket; + struct sockaddr_un m_sockaddr; + int m_serverSocket; #endif - }; + }; } #endif //INTERPROCESSCOMMUNICATOR_H \ No newline at end of file diff --git a/src/app/aura.cpp b/src/app/aura.cpp index 278617c..15d1ccf 100644 --- a/src/app/aura.cpp +++ b/src/app/aura.cpp @@ -14,24 +14,39 @@ using namespace Nickvision::Filesystem; namespace Nickvision::App { - Aura::Aura() + Aura::Aura() : m_initialized{ false } - { + { - } + } - Aura::~Aura() - { + Aura::~Aura() + { if(m_initialized) { curl_global_cleanup(); } - } + } - bool Aura::init(const std::string& id, const std::string& name, const std::string& englishShortName) - { + bool Aura::init(const std::string& id, const std::string& name, const std::string& englishShortName) + { if(!m_initialized) { + //Get executable's directory path +#ifdef _WIN32 + char pth[MAX_PATH]; + DWORD len{ GetModuleFileNameA(nullptr, pth, sizeof(pth)) }; + if(len > 0) + { + m_executableDirectory = std::filesystem::path(std::string(pth, len)).parent_path(); + } + else + { + throw std::runtime_error("Unable to get executable directory."); + } +#elif defined(__linux__) + m_executableDirectory = std::filesystem::canonical("/proc/self/exe").parent_path(); +#endif //Setup AppInfo m_appInfo.setId(id); m_appInfo.setName(name); @@ -47,95 +62,89 @@ namespace Nickvision::App { throw std::runtime_error("Unable to initialize gettext."); } - //Get executable's directory path -#ifdef _WIN32 - char pth[MAX_PATH]; - DWORD len{ GetModuleFileNameA(nullptr, pth, sizeof(pth)) }; - if(len > 0) - { - m_executableDirectory = std::filesystem::path(std::string(pth, len)).parent_path(); - } - else - { - throw std::runtime_error("Unable to get executable directory."); - } -#elif defined(__linux__) - m_executableDirectory = std::filesystem::canonical("/proc/self/exe").parent_path(); -#endif m_initialized = true; } return m_initialized; - } - - AppInfo& Aura::getAppInfo() - { - return m_appInfo; - } + } - const std::filesystem::path& Aura::getExecutableDirectory() const - { + const std::filesystem::path& Aura::getExecutableDirectory() const + { return m_executableDirectory; - } + } + + AppInfo& Aura::getAppInfo() + { + return m_appInfo; + } - std::string Aura::getEnvVar(const std::string& key) - { - char* var{ std::getenv(key.c_str()) }; - if (var) - { - return { var }; - } - return ""; - } + InterProcessCommunicator& Aura::getIPC() + { + if(!m_ipc) + { + m_ipc = std::make_unique(m_appInfo.getId()); + } + return *m_ipc; + } + + std::string Aura::getEnvVar(const std::string& key) + { + char* var{ std::getenv(key.c_str()) }; + if (var) + { + return { var }; + } + return ""; + } - bool Aura::setEnvVar(const std::string& key, const std::string& value) - { + bool Aura::setEnvVar(const std::string& key, const std::string& value) + { #ifdef _WIN32 - return _putenv_s(key.c_str(), value.c_str()) == 0; + return _putenv_s(key.c_str(), value.c_str()) == 0; #elif defined(__linux__) - return setenv(key.c_str(), value.c_str(), true) == 0; + return setenv(key.c_str(), value.c_str(), true) == 0; #endif - } + } - const std::filesystem::path& Aura::findDependency(std::string dependency) - { + const std::filesystem::path& Aura::findDependency(std::string dependency) + { #ifdef _WIN32 - if (!std::filesystem::path(dependency).has_extension()) - { - dependency += ".exe"; - } + if (!std::filesystem::path(dependency).has_extension()) + { + dependency += ".exe"; + } #endif - if (m_dependencies.contains(dependency)) - { - const std::filesystem::path& location{ m_dependencies[dependency] }; - if (std::filesystem::exists(location)) - { - return location; - } - } - m_dependencies[dependency] = std::filesystem::path(); - std::filesystem::path path{ getExecutableDirectory() / dependency }; - if (std::filesystem::exists(path)) - { - m_dependencies[dependency] = path; - } - else - { - for (const std::filesystem::path& dir : SystemDirectories::getPath()) - { - path = { dir / dependency }; - if (std::filesystem::exists(path) && dir.string().find("AppData\\Local\\Microsoft\\WindowsApps") == std::string::npos) - { - m_dependencies[dependency] = path; - break; - } - } - } - return m_dependencies[dependency]; - } + if (m_dependencies.contains(dependency)) + { + const std::filesystem::path& location{ m_dependencies[dependency] }; + if (std::filesystem::exists(location)) + { + return location; + } + } + m_dependencies[dependency] = std::filesystem::path(); + std::filesystem::path path{ getExecutableDirectory() / dependency }; + if (std::filesystem::exists(path)) + { + m_dependencies[dependency] = path; + } + else + { + for (const std::filesystem::path& dir : SystemDirectories::getPath()) + { + path = { dir / dependency }; + if (std::filesystem::exists(path) && dir.string().find("AppData\\Local\\Microsoft\\WindowsApps") == std::string::npos) + { + m_dependencies[dependency] = path; + break; + } + } + } + return m_dependencies[dependency]; + } Aura& Aura::getActive() - { - static Aura aura; + { + static Aura aura; return aura; - } + } } \ No newline at end of file diff --git a/src/app/interprocesscommunicator.cpp b/src/app/interprocesscommunicator.cpp index 5477a4d..346355a 100644 --- a/src/app/interprocesscommunicator.cpp +++ b/src/app/interprocesscommunicator.cpp @@ -1,7 +1,6 @@ #include "app/interprocesscommunicator.h" #include #include -#include "app/aura.h" #ifdef __linux__ #include #include @@ -9,175 +8,175 @@ namespace Nickvision::App { - InterProcessCommunicator::InterProcessCommunicator() - : m_serverRunning{ false } - { + InterProcessCommunicator::InterProcessCommunicator(const std::string& id) + : m_serverRunning{ false } + { #ifdef _WIN32 - m_path = "\\\\.\\pipe\\" + Aura::getActive().getAppInfo().getId(); - m_serverPipe = nullptr; - WIN32_FIND_DATAA fd; - HANDLE find{ FindFirstFileA(m_path.c_str(), &fd) }; - if (find == INVALID_HANDLE_VALUE) //no server exists - { - m_serverPipe = CreateNamedPipeA(m_path.c_str(), PIPE_ACCESS_INBOUND | FILE_FLAG_OVERLAPPED, PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, 1, 0, 0, NMPWAIT_USE_DEFAULT_WAIT, nullptr); - if (m_serverPipe == INVALID_HANDLE_VALUE) - { - throw std::runtime_error("Unable to start IPC server."); - } - m_serverRunning = true; - FindClose(find); - } + m_path = "\\\\.\\pipe\\" + id; + m_serverPipe = nullptr; + WIN32_FIND_DATAA fd; + HANDLE find{ FindFirstFileA(m_path.c_str(), &fd) }; + if (find == INVALID_HANDLE_VALUE) //no server exists + { + m_serverPipe = CreateNamedPipeA(m_path.c_str(), PIPE_ACCESS_INBOUND | FILE_FLAG_OVERLAPPED, PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, 1, 0, 0, NMPWAIT_USE_DEFAULT_WAIT, nullptr); + if (m_serverPipe == INVALID_HANDLE_VALUE) + { + throw std::runtime_error("Unable to start IPC server."); + } + m_serverRunning = true; + FindClose(find); + } #elif defined(__linux__) - m_path = "/tmp/" + Aura::getActive().getAppInfo().getId(); - if (m_path.size() >= 108) - { - throw std::runtime_error("Unable to create IPC server. Application ID is too long. Must be < 103 characters."); - } - memset(&m_sockaddr, 0, sizeof(m_sockaddr)); - m_sockaddr.sun_family = AF_UNIX; - strcpy(m_sockaddr.sun_path, m_path.c_str()); - m_serverSocket = socket(AF_UNIX, SOCK_SEQPACKET, 0); - if (m_serverSocket == -1) - { - throw std::runtime_error("Unable to check IPC server."); - } - if (bind(m_serverSocket, (const struct sockaddr*)&m_sockaddr, sizeof(m_sockaddr)) != -1) //no server exists - { - if (listen(m_serverSocket, 5) == -1) - { - throw std::runtime_error("Unable to listen to IPC socket."); - } - m_serverRunning = true; - } - else - { - close(m_serverSocket); - m_serverSocket = -1; - } + m_path = "/tmp/" + id; + if (m_path.size() >= 108) + { + throw std::runtime_error("Unable to create IPC server. Application ID is too long. Must be < 103 characters."); + } + memset(&m_sockaddr, 0, sizeof(m_sockaddr)); + m_sockaddr.sun_family = AF_UNIX; + strcpy(m_sockaddr.sun_path, m_path.c_str()); + m_serverSocket = socket(AF_UNIX, SOCK_SEQPACKET, 0); + if (m_serverSocket == -1) + { + throw std::runtime_error("Unable to check IPC server."); + } + if (bind(m_serverSocket, (const struct sockaddr*)&m_sockaddr, sizeof(m_sockaddr)) != -1) //no server exists + { + if (listen(m_serverSocket, 5) == -1) + { + throw std::runtime_error("Unable to listen to IPC socket."); + } + m_serverRunning = true; + } + else + { + close(m_serverSocket); + m_serverSocket = -1; + } #endif - if (m_serverRunning) - { - m_server = std::jthread(&InterProcessCommunicator::runServer, this); - } - } + if (m_serverRunning) + { + m_server = std::jthread(&InterProcessCommunicator::runServer, this); + } + } - InterProcessCommunicator::~InterProcessCommunicator() - { - m_serverRunning = false; + InterProcessCommunicator::~InterProcessCommunicator() + { + m_serverRunning = false; #ifdef _WIN32 - if (m_serverPipe) - { - CancelSynchronousIo(m_serverPipe); - CloseHandle(m_serverPipe); - } + if (m_serverPipe) + { + CancelSynchronousIo(m_serverPipe); + CloseHandle(m_serverPipe); + } #elif defined(__linux__) - if (m_serverSocket != -1) - { - int clientSocket{ socket(AF_UNIX, SOCK_SEQPACKET, 0) }; - connect(clientSocket, (const struct sockaddr*)&m_sockaddr, sizeof(m_sockaddr)); - close(clientSocket); - close(m_serverSocket); - unlink(m_path.c_str()); - } + if (m_serverSocket != -1) + { + int clientSocket{ socket(AF_UNIX, SOCK_SEQPACKET, 0) }; + connect(clientSocket, (const struct sockaddr*)&m_sockaddr, sizeof(m_sockaddr)); + close(clientSocket); + close(m_serverSocket); + unlink(m_path.c_str()); + } #endif - } + } - Events::Event>>& InterProcessCommunicator::commandReceived() - { - return m_commandReceived; - } + Events::Event>>& InterProcessCommunicator::commandReceived() + { + return m_commandReceived; + } - bool InterProcessCommunicator::isServer() const - { - return m_serverRunning; - } + bool InterProcessCommunicator::isServer() const + { + return m_serverRunning; + } - bool InterProcessCommunicator::isClient() const - { - return !m_serverRunning; - } + bool InterProcessCommunicator::isClient() const + { + return !m_serverRunning; + } - bool InterProcessCommunicator::communicate(const std::vector& args, bool exitIfClient) - { - if (m_serverRunning) - { - m_commandReceived({ args }); - return true; - } - if (!args.empty()) - { - std::string argc{ std::to_string(args.size()) }; + bool InterProcessCommunicator::communicate(const std::vector& args, bool exitIfClient) + { + if (m_serverRunning) + { + m_commandReceived({ args }); + return true; + } + if (!args.empty()) + { + std::string argc{ std::to_string(args.size()) }; #ifdef _WIN32 - HANDLE clientPipe{ CreateFileA(m_path.c_str(), GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr) }; - if (clientPipe == INVALID_HANDLE_VALUE) - { - return false; - } - WriteFile(clientPipe, argc.c_str(), DWORD(argc.size()), nullptr, nullptr); - for (const std::string& arg : args) - { - WriteFile(clientPipe, arg.c_str(), DWORD(arg.size()), nullptr, nullptr); - } - CloseHandle(clientPipe); + HANDLE clientPipe{ CreateFileA(m_path.c_str(), GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr) }; + if (clientPipe == INVALID_HANDLE_VALUE) + { + return false; + } + WriteFile(clientPipe, argc.c_str(), DWORD(argc.size()), nullptr, nullptr); + for (const std::string& arg : args) + { + WriteFile(clientPipe, arg.c_str(), DWORD(arg.size()), nullptr, nullptr); + } + CloseHandle(clientPipe); #elif defined(__linux__) - int clientSocket{ socket(AF_UNIX, SOCK_SEQPACKET, 0) }; - if (connect(clientSocket, (const struct sockaddr*)&m_sockaddr, sizeof(m_sockaddr)) == -1) - { - return false; - } - write(clientSocket, argc.c_str(), argc.size()); - for (const std::string& arg : args) - { - write(clientSocket, arg.c_str(), arg.size()); - } - close(clientSocket); + int clientSocket{ socket(AF_UNIX, SOCK_SEQPACKET, 0) }; + if (connect(clientSocket, (const struct sockaddr*)&m_sockaddr, sizeof(m_sockaddr)) == -1) + { + return false; + } + write(clientSocket, argc.c_str(), argc.size()); + for (const std::string& arg : args) + { + write(clientSocket, arg.c_str(), arg.size()); + } + close(clientSocket); #endif - } - if (exitIfClient) - { - std::exit(0); - } - return true; - } + } + if (exitIfClient) + { + std::exit(0); + } + return true; + } - void InterProcessCommunicator::runServer() - { - std::vector buffer(1024); - while (m_serverRunning) - { + void InterProcessCommunicator::runServer() + { + std::vector buffer(1024); + while (m_serverRunning) + { #ifdef _WIN32 - if (ConnectNamedPipe(m_serverPipe, nullptr)) - { - DWORD read; - ReadFile(m_serverPipe, &buffer[0], DWORD(buffer.size()), &read, nullptr); - std::vector args(std::stoull({ &buffer[0], read })); - for (size_t i = 0; i < args.size(); i++) - { - ReadFile(m_serverPipe, &buffer[0], DWORD(buffer.size()), &read, nullptr); - args[i] = { &buffer[0], read }; - } - m_commandReceived({ args }); - DisconnectNamedPipe(m_serverPipe); - } + if (ConnectNamedPipe(m_serverPipe, nullptr)) + { + DWORD read; + ReadFile(m_serverPipe, &buffer[0], DWORD(buffer.size()), &read, nullptr); + std::vector args(std::stoull({ &buffer[0], read })); + for (size_t i = 0; i < args.size(); i++) + { + ReadFile(m_serverPipe, &buffer[0], DWORD(buffer.size()), &read, nullptr); + args[i] = { &buffer[0], read }; + } + m_commandReceived({ args }); + DisconnectNamedPipe(m_serverPipe); + } #elif defined(__linux__) - int clientSocket{ accept(m_serverSocket, nullptr, nullptr) }; - if (!m_serverRunning) - { - break; - } - if (clientSocket != -1) - { - ssize_t r{ read(clientSocket, &buffer[0], buffer.size()) }; - std::vector args(std::stoull({ &buffer[0], static_cast(r < 0 ? 0 : r) })); - for (size_t i = 0; i < args.size(); i++) - { - r = read(clientSocket, &buffer[0], buffer.size()); - args[i] = { &buffer[0], static_cast(r < 0 ? 0 : r) }; - } - m_commandReceived({ args }); - close(clientSocket); - } + int clientSocket{ accept(m_serverSocket, nullptr, nullptr) }; + if (!m_serverRunning) + { + break; + } + if (clientSocket != -1) + { + ssize_t r{ read(clientSocket, &buffer[0], buffer.size()) }; + std::vector args(std::stoull({ &buffer[0], static_cast(r < 0 ? 0 : r) })); + for (size_t i = 0; i < args.size(); i++) + { + r = read(clientSocket, &buffer[0], buffer.size()); + args[i] = { &buffer[0], static_cast(r < 0 ? 0 : r) }; + } + m_commandReceived({ args }); + close(clientSocket); + } #endif - } - } + } + } } \ No newline at end of file diff --git a/tests/ipctests.cpp b/tests/ipctests.cpp index 9413df1..2a21a2c 100644 --- a/tests/ipctests.cpp +++ b/tests/ipctests.cpp @@ -11,13 +11,10 @@ static std::vector args{ "test1", "test2" }; class IPCTest : public testing::Test { public: - static std::unique_ptr m_server; - static void SetUpTestSuite() { Aura::getActive().init("org.nickvision.aura.test", "Nickvision Aura Tests", "Aura Tests"); - m_server = std::make_unique(); - m_server->commandReceived() += onCommandReceived; + Aura::getActive().getIPC().commandReceived() += onCommandReceived; } static int getReceived() @@ -39,11 +36,10 @@ class IPCTest : public testing::Test std::mutex IPCTest::m_mutex = {}; int IPCTest::m_received = 0; -std::unique_ptr IPCTest::m_server = nullptr; TEST_F(IPCTest, CheckServerStatus) { - ASSERT_TRUE(m_server->isServer()); + ASSERT_TRUE(Aura::getActive().getIPC().isServer()); } TEST_F(IPCTest, Client1Send) @@ -53,7 +49,7 @@ TEST_F(IPCTest, Client1Send) ASSERT_TRUE(true); return; } - InterProcessCommunicator client; + InterProcessCommunicator client{ Aura::getActive().getAppInfo().getId() }; ASSERT_TRUE(client.isClient()); ASSERT_TRUE(client.communicate(args)); } @@ -62,9 +58,4 @@ TEST_F(IPCTest, CheckServerReceived) { std::this_thread::sleep_for(std::chrono::seconds(5)); ASSERT_TRUE(getReceived() > 0 || Aura::getActive().getEnvVar("GITHUB_ACTIONS") == "true"); -} - -TEST_F(IPCTest, Cleanup) -{ - ASSERT_NO_THROW(m_server.reset()); } \ No newline at end of file From 222a9225d500cb1d41552f36d5d4d4f5c6028fd1 Mon Sep 17 00:00:00 2001 From: Nick Logozzo Date: Mon, 29 Jan 2024 17:02:31 -0500 Subject: [PATCH 03/10] Updater - Better Updater API - Updater's constructor must now always take a gitHubRepo URL argument. It will no longer use `Aura::getActive().getAppInfo().getSourceRepo()` if an empty argument is provided. --- docs/update.md | 6 +- include/helpers/stringhelpers.h | 203 +++++++++++---------- include/update/updater.h | 108 ++++++------ src/helpers/stringhelpers.cpp | 304 ++++++++++++++++---------------- src/update/updater.cpp | 194 ++++++++++---------- tests/updatertests.cpp | 2 +- 6 files changed, 415 insertions(+), 402 deletions(-) diff --git a/docs/update.md b/docs/update.md index 3cdfd7c..ad12edd 100644 --- a/docs/update.md +++ b/docs/update.md @@ -18,11 +18,11 @@ Path: `Nickvision::Update::Updater` ### Methods - ```cpp - Updater(std::string githubRepoUrl = "") + Updater(std::string githubRepoUrl) ``` - Constructs an Updater. - - Accepts: The url of a GitHub repo to check for updates, githubRepoUrl. If githubRepoUrl is empty, the url will attempt to be determined from `Aura::getActive().getAppInfo().getSourceRepo()`. - - Throws: `std::invalid_argument` if no valid GitHub url can be determined. + - Accepts: The url of a GitHub repo to check for updates, githubRepoUrl. + - Throws: `std::invalid_argument` if the GitHub url is not of valid format - ```cpp Nickvision::Version fetchCurrentStableVersion() ``` diff --git a/include/helpers/stringhelpers.h b/include/helpers/stringhelpers.h index f3ba5eb..089f93c 100644 --- a/include/helpers/stringhelpers.h +++ b/include/helpers/stringhelpers.h @@ -9,107 +9,116 @@ namespace Nickvision::StringHelpers { - template - concept StringImplicitlyConstructible = std::is_constructible_v && std::is_convertible_v; + template + concept StringImplicitlyConstructible = std::is_constructible_v && std::is_convertible_v; - /** - * @brief Gets whether or not the provided string is a valid url - * @param s The string to check - * @return True if the string is a valid url, else false - */ - bool isValidUrl(const std::string& s); /** - * @brief Concatenates the elements of a string list using the specified separator between each element. - * @param values The list of strings to join - * @param delimiter The string to use as a separator between each element - * @param delimitLast Whether or not to include the separator for the last joined element - * @return A single string that consists of all elements of the string list separated by the delimiter - */ - std::string join(const std::vector& values, const std::string& separator, bool separateLast = true); - /** - * @brief Generates a new guid (uuid v4) value. - * @return The guid value - */ - std::string newGuid(); - /** - * @brief Replaces a substring within a string with a new string. - * @param s The string to work on - * @param toRepalce The substring to be replaced - * @param replace The new string to replace with - * @return The new replaced string - */ - std::string replace(std::string s, const std::string& toReplace, const std::string& replace); - /** - * @brief Splits a string based on a delimiter. - * @tparam T The type of the resulting splits (must be a type that can be implicitly converted to string) - * @param s The string to split - * @param delimiter The delimiter to split the string on - * @return The splits of the string - */ - template - std::vector split(std::string s, const std::string& delimiter) - { - std::vector splits; - size_t pos{ 0 }; - while ((pos = s.find(delimiter)) != std::string::npos) - { - std::string split{ s.substr(0, pos) }; - splits.push_back(split); - s.erase(0, pos + 1); - } - if (!s.empty()) - { - splits.push_back(s); - } - return splits; - } - /** - * @brief Converts a string to an unsigned int - * @param s The string to convert - * @param idx The address of a size_t to store the number of characters processed - * @param base The number base - * @return The unsigned int version of the string - * @return UINT_MAX if the converted string is too long - * @return 0 if error - */ - unsigned int stoui(const std::string& s, size_t* idx = nullptr, int base = 10); - /** - * @brief Gets a fully lowercase string from the provided string. - * @param s The string to get lowercase - * @return The new lowercase string - */ - std::string toLower(std::string s); + * @brief Gets whether or not the provided string is a valid url + * @param s The string to check + * @return True if the string is a valid url, else false + */ + bool isValidUrl(const std::string& s); /** - * @brief Converts the wstring to a string. - * @param s The wstring to convert - * @return The string version of the wstring - */ - std::string toString(const std::wstring& s); - /** - * @brief Gets a fully uppercase string from the provided string. - * @param s The string to get uppercase - * @return The new uppercase string - */ - std::string toUpper(std::string s); + * @brief Concatenates the elements of a string list using the specified separator between each element. + * @param values The list of strings to join + * @param delimiter The string to use as a separator between each element + * @param delimitLast Whether or not to include the separator for the last joined element + * @return A single string that consists of all elements of the string list separated by the delimiter + */ + std::string join(const std::vector& values, const std::string& separator, bool separateLast = true); /** - * @brief Converts the string to a wstring. - * @param s The string to convert - * @return The wstring version of the string - */ - std::wstring toWstring(const std::string& s); - /** - * @brief Trims whitespace form the beginning and end of a string. - * @param s The string to trim (unmodified) - * @return The new trimmed string - */ - std::string trim(const std::string& s); - /** - * @brief Trims the delimiter character form the beginning and end of a string. - * @param s The string to trim (unmodified) - * @param delimiter The character to trim - * @return The new trimmed string - */ - std::string trim(const std::string& s, char delimiter); + * @brief Generates a new guid (uuid v4) value. + * @return The guid value + */ + std::string newGuid(); + /** + * @brief Replaces a substring within a string with a new string. + * @param s The string to work on + * @param toRepalce The substring to be replaced + * @param replace The new string to replace with + * @return The new replaced string + */ + std::string replace(std::string s, const std::string& toReplace, const std::string& replace); + /** + * @brief Splits a string based on a delimiter. + * @tparam T The type of the resulting splits (must be a type that can be implicitly converted to string) + * @param s The string to split + * @param delimiter The delimiter to split the string on + * @return The splits of the string + */ + template + std::vector split(std::string s, const std::string& delimiter) + { + if(s.empty()) + { + return {}; + } + std::vector splits; + if(delimiter.empty()) + { + splits.push_back(s); + return splits; + } + size_t pos{ 0 }; + while ((pos = s.find(delimiter)) != std::string::npos) + { + std::string split{ s.substr(0, pos) }; + splits.push_back(split); + s.erase(0, pos + 1); + } + if (!s.empty()) + { + splits.push_back(s); + } + return splits; + } + /** + * @brief Converts a string to an unsigned int + * @param s The string to convert + * @param idx The address of a size_t to store the number of characters processed + * @param base The number base + * @return The unsigned int version of the string + * @return UINT_MAX if the converted string is too long + * @return 0 if error + */ + unsigned int stoui(const std::string& s, size_t* idx = nullptr, int base = 10); + /** + * @brief Gets a fully lowercase string from the provided string. + * @param s The string to get lowercase + * @return The new lowercase string + */ + std::string toLower(std::string s); + /** + * @brief Converts the wstring to a string. + * @param s The wstring to convert + * @return The string version of the wstring + */ + std::string toString(const std::wstring& s); + /** + * @brief Gets a fully uppercase string from the provided string. + * @param s The string to get uppercase + * @return The new uppercase string + */ + std::string toUpper(std::string s); + /** + * @brief Converts the string to a wstring. + * @param s The string to convert + * @return The wstring version of the string + */ + std::wstring toWstring(const std::string& s); + /** + * @brief Trims whitespace form the beginning and end of a string. + * @param s The string to trim (unmodified) + * @return The new trimmed string + */ + std::string trim(const std::string& s); + /** + * @brief Trims the delimiter character form the beginning and end of a string. + * @param s The string to trim (unmodified) + * @param delimiter The character to trim + * @return The new trimmed string + */ + std::string trim(const std::string& s, char delimiter); } diff --git a/include/update/updater.h b/include/update/updater.h index 5fce05f..3aea2a6 100644 --- a/include/update/updater.h +++ b/include/update/updater.h @@ -7,72 +7,72 @@ namespace Nickvision::Update { - /** - * @brief An object to check for application updates through GitHub. - */ - class Updater - { - public: - /** - * @brief Constructs an Updater. - * @param githubRepoUrl The url of the GitHub repo to fetch updates for. Must be a valid github url. If the url is invalid, Updater will attempt to get a repo url from Aura - * @throw std::invalid_argument Thrown if no valid GitHub url can be determined - */ - Updater(std::string githubRepoUrl = ""); + /** + * @brief An object to check for application updates through GitHub. + */ + class Updater + { + public: + /** + * @brief Constructs an Updater. + * @param githubRepoUrl The url of the GitHub repo to fetch updates for + * @throw std::invalid_argument Thrown if the GitHub url is not of valid format + */ + Updater(std::string githubRepoUrl); /** * @brief Constructs an Updater via copy. * @param u The object to copy */ Updater(const Updater& u); - /** + /** * @brief Constructs an Updater via move. * @param u The object to move */ Updater(Updater&& u) noexcept; - /** - * @brief Gets the latest stable version from the GitHub repo. - * @return The current stable version if available, else empty Version - */ - Version fetchCurrentStableVersion(); - /** - * @brief Gets the latest preview version from the GitHub repo. - * @return The current preview version if available, else empty Version - */ - Version fetchCurrentPreviewVersion(); + /** + * @brief Gets the latest stable version from the GitHub repo. + * @return The current stable version if available, else empty Version + */ + Version fetchCurrentStableVersion(); + /** + * @brief Gets the latest preview version from the GitHub repo. + * @return The current preview version if available, else empty Version + */ + Version fetchCurrentPreviewVersion(); #ifdef _WIN32 - /** - * @brief Downloads and installs an application update for Windows. getCurrentStableVersion or getCurrentPreviewVersion should be called first before running this method. This method will force quit the current running application to install the update. - * @param versionType The type of version update to install - * @return True if successful, else false - */ - bool windowsUpdate(VersionType versionType); + /** + * @brief Downloads and installs an application update for Windows. getCurrentStableVersion or getCurrentPreviewVersion should be called first before running this method. This method will force quit the current running application to install the update. + * @param versionType The type of version update to install + * @return True if successful, else false + */ + bool windowsUpdate(VersionType versionType); #endif - /** - * @brief Copies an Updater. - * @param u The Updater to copy - * @return this - */ - Updater& operator=(const Updater& u); - /** - * @brief Moves an Updater. - * @param u The Updater to move - * @return this - */ - Updater& operator=(Updater&& u) noexcept; + /** + * @brief Copies an Updater. + * @param u The Updater to copy + * @return this + */ + Updater& operator=(const Updater& u); + /** + * @brief Moves an Updater. + * @param u The Updater to move + * @return this + */ + Updater& operator=(Updater&& u) noexcept; - private: - /** - * @brief Gets the latest version of the provided type from the GitHub repo - * @param versionType The type of the version to get - * @return The current version of the proivded type if available, else empty Version - */ - Version fetchCurrentVersion(VersionType versionType); - mutable std::mutex m_mutex; - std::string m_repoOwner; - std::string m_repoName; - int m_latestStableReleaseId; - int m_latestPreviewReleaseId; - }; + private: + /** + * @brief Gets the latest version of the provided type from the GitHub repo + * @param versionType The type of the version to get + * @return The current version of the proivded type if available, else empty Version + */ + Version fetchCurrentVersion(VersionType versionType); + mutable std::mutex m_mutex; + std::string m_repoOwner; + std::string m_repoName; + int m_latestStableReleaseId; + int m_latestPreviewReleaseId; + }; } #endif //UPDATER_H \ No newline at end of file diff --git a/src/helpers/stringhelpers.cpp b/src/helpers/stringhelpers.cpp index 17779c1..3bf11c8 100644 --- a/src/helpers/stringhelpers.cpp +++ b/src/helpers/stringhelpers.cpp @@ -16,171 +16,179 @@ namespace Nickvision { - bool StringHelpers::isValidUrl(const std::string& s) - { - if (s.empty()) - { - return false; - } - CURLU* url{ curl_url() }; - int res{ curl_url_set(url, CURLUPART_URL, s.c_str(), 0) }; - curl_url_cleanup(url); - return res == CURLUE_OK; - } + bool StringHelpers::isValidUrl(const std::string& s) + { + if (s.empty()) + { + return false; + } + CURLU* url{ curl_url() }; + int res{ curl_url_set(url, CURLUPART_URL, s.c_str(), 0) }; + curl_url_cleanup(url); + return res == CURLUE_OK; + } std::string StringHelpers::join(const std::vector& values, const std::string& separator, bool separateLast) - { - std::stringstream builder; - for(size_t i = 0; i < values.size(); i++) - { - const std::string& value{ values[i] }; - builder << value; - if(i != values.size() - 1 || (i == values.size() - 1 && separateLast)) - { - builder << separator; - } - } - return builder.str(); - } + { + std::stringstream builder; + for(size_t i = 0; i < values.size(); i++) + { + const std::string& value{ values[i] }; + builder << value; + if(i != values.size() - 1 || (i == values.size() - 1 && separateLast)) + { + builder << separator; + } + } + return builder.str(); + } std::string StringHelpers::newGuid() - { - std::array guid; -#ifdef _WIN32 - GUID win; - CoInitializeEx(nullptr, COINIT_MULTITHREADED); - if (CoCreateGuid(&win) != S_OK) - { - return ""; - } - guid = { - (unsigned char)((win.Data1 >> 24) & 0xFF), - (unsigned char)((win.Data1 >> 16) & 0xFF), - (unsigned char)((win.Data1 >> 8) & 0xFF), - (unsigned char)((win.Data1) & 0xff), + { + std::array guid; + #ifdef _WIN32 + GUID win; + CoInitializeEx(nullptr, COINIT_MULTITHREADED); + if (CoCreateGuid(&win) != S_OK) + { + return ""; + } + guid = { + (unsigned char)((win.Data1 >> 24) & 0xFF), + (unsigned char)((win.Data1 >> 16) & 0xFF), + (unsigned char)((win.Data1 >> 8) & 0xFF), + (unsigned char)((win.Data1) & 0xff), - (unsigned char)((win.Data2 >> 8) & 0xFF), - (unsigned char)((win.Data2) & 0xff), + (unsigned char)((win.Data2 >> 8) & 0xFF), + (unsigned char)((win.Data2) & 0xff), - (unsigned char)((win.Data3 >> 8) & 0xFF), - (unsigned char)((win.Data3) & 0xFF), + (unsigned char)((win.Data3 >> 8) & 0xFF), + (unsigned char)((win.Data3) & 0xFF), - (unsigned char)win.Data4[0], - (unsigned char)win.Data4[1], - (unsigned char)win.Data4[2], - (unsigned char)win.Data4[3], - (unsigned char)win.Data4[4], - (unsigned char)win.Data4[5], - (unsigned char)win.Data4[6], - (unsigned char)win.Data4[7] - }; -#elif defined(__linux__) - uuid_generate(guid.data()); -#endif - std::ostringstream out; - out << std::setfill('0') << std::setw(2) << std::hex << static_cast(guid[0]); - out << std::setfill('0') << std::setw(2) << std::hex << static_cast(guid[1]); - out << std::setfill('0') << std::setw(2) << std::hex << static_cast(guid[2]); - out << std::setfill('0') << std::setw(2) << std::hex << static_cast(guid[3]); - out << "-"; - out << std::setfill('0') << std::setw(2) << std::hex << static_cast(guid[4]); - out << std::setfill('0') << std::setw(2) << std::hex << static_cast(guid[5]); - out << "-"; - out << std::setfill('0') << std::setw(2) << std::hex << static_cast(guid[6]); - out << std::setfill('0') << std::setw(2) << std::hex << static_cast(guid[7]); - out << "-"; - out << std::setfill('0') << std::setw(2) << std::hex << static_cast(guid[8]); - out << std::setfill('0') << std::setw(2) << std::hex << static_cast(guid[9]); - out << "-"; - out << std::setfill('0') << std::setw(2) << std::hex << static_cast(guid[10]); - out << std::setfill('0') << std::setw(2) << std::hex << static_cast(guid[11]); - out << std::setfill('0') << std::setw(2) << std::hex << static_cast(guid[12]); - out << std::setfill('0') << std::setw(2) << std::hex << static_cast(guid[13]); - out << std::setfill('0') << std::setw(2) << std::hex << static_cast(guid[14]); - out << std::setfill('0') << std::setw(2) << std::hex << static_cast(guid[15]); - return out.str(); - } + (unsigned char)win.Data4[0], + (unsigned char)win.Data4[1], + (unsigned char)win.Data4[2], + (unsigned char)win.Data4[3], + (unsigned char)win.Data4[4], + (unsigned char)win.Data4[5], + (unsigned char)win.Data4[6], + (unsigned char)win.Data4[7] + }; + #elif defined(__linux__) + uuid_generate(guid.data()); + #endif + std::ostringstream out; + out << std::setfill('0') << std::setw(2) << std::hex << static_cast(guid[0]); + out << std::setfill('0') << std::setw(2) << std::hex << static_cast(guid[1]); + out << std::setfill('0') << std::setw(2) << std::hex << static_cast(guid[2]); + out << std::setfill('0') << std::setw(2) << std::hex << static_cast(guid[3]); + out << "-"; + out << std::setfill('0') << std::setw(2) << std::hex << static_cast(guid[4]); + out << std::setfill('0') << std::setw(2) << std::hex << static_cast(guid[5]); + out << "-"; + out << std::setfill('0') << std::setw(2) << std::hex << static_cast(guid[6]); + out << std::setfill('0') << std::setw(2) << std::hex << static_cast(guid[7]); + out << "-"; + out << std::setfill('0') << std::setw(2) << std::hex << static_cast(guid[8]); + out << std::setfill('0') << std::setw(2) << std::hex << static_cast(guid[9]); + out << "-"; + out << std::setfill('0') << std::setw(2) << std::hex << static_cast(guid[10]); + out << std::setfill('0') << std::setw(2) << std::hex << static_cast(guid[11]); + out << std::setfill('0') << std::setw(2) << std::hex << static_cast(guid[12]); + out << std::setfill('0') << std::setw(2) << std::hex << static_cast(guid[13]); + out << std::setfill('0') << std::setw(2) << std::hex << static_cast(guid[14]); + out << std::setfill('0') << std::setw(2) << std::hex << static_cast(guid[15]); + return out.str(); + } std::string StringHelpers::replace(std::string s, const std::string& toReplace, const std::string& replace) - { - if (s.empty() || toReplace.empty()) - { - return s; - } - size_t r{ s.find(toReplace) }; - if (r == std::string::npos) - { - return s; - } - return s.replace(r, toReplace.size(), replace); - } + { + if (s.empty() || toReplace.empty()) + { + return s; + } + size_t r{ s.find(toReplace) }; + if (r == std::string::npos) + { + return s; + } + return s.replace(r, toReplace.size(), replace); + } unsigned int StringHelpers::stoui(const std::string& s, size_t* idx, int base) - { - try - { - unsigned long ul{ std::stoul(s, idx, base) }; - if (ul > (std::numeric_limits::max)()) - { - return (std::numeric_limits::max)(); - } - return static_cast(ul); - } - catch (...) - { - return 0; - } - } + { + try + { + unsigned long ul{ std::stoul(s, idx, base) }; + if (ul > (std::numeric_limits::max)()) + { + return (std::numeric_limits::max)(); + } + return static_cast(ul); + } + catch (...) + { + return 0; + } + } - std::string StringHelpers::toLower(std::string s) - { - std::transform(s.begin(), s.end(), s.begin(), [](unsigned char c) { return std::tolower(c); }); - return s; - } + std::string StringHelpers::toLower(std::string s) + { + std::transform(s.begin(), s.end(), s.begin(), [](unsigned char c) { return std::tolower(c); }); + return s; + } std::string StringHelpers::toString(const std::wstring& s) - { - std::wstring_convert> converter; - return converter.to_bytes(s); - } + { + std::wstring_convert> converter; + return converter.to_bytes(s); + } - std::string StringHelpers::toUpper(std::string s) - { - std::transform(s.begin(), s.end(), s.begin(), [](unsigned char c) { return std::toupper(c); }); - return s; - } + std::string StringHelpers::toUpper(std::string s) + { + std::transform(s.begin(), s.end(), s.begin(), [](unsigned char c) { return std::toupper(c); }); + return s; + } std::wstring StringHelpers::toWstring(const std::string& s) - { - std::wstring_convert> converter; - return converter.from_bytes(s); - } + { + std::wstring_convert> converter; + return converter.from_bytes(s); + } - std::string StringHelpers::trim(const std::string& s) - { - std::string result{ s }; - result.erase(std::find_if(result.rbegin(), result.rend(), [](unsigned char ch) - { - return !std::isspace(ch); - }).base(), result.end()); - result.erase(result.begin(), std::find_if(result.begin(), result.end(), [](unsigned char ch) - { - return !std::isspace(ch); - })); - return result; - } + std::string StringHelpers::trim(const std::string& s) + { + if(s.empty()) + { + return s; + } + std::string result{ s }; + result.erase(std::find_if(result.rbegin(), result.rend(), [](unsigned char ch) + { + return !std::isspace(ch); + }).base(), result.end()); + result.erase(result.begin(), std::find_if(result.begin(), result.end(), [](unsigned char ch) + { + return !std::isspace(ch); + })); + return result; + } - std::string StringHelpers::trim(const std::string& s, char delimiter) - { - std::string result{ s }; - result.erase(std::find_if(result.rbegin(), result.rend(), [delimiter](char ch) - { - return ch != delimiter; - }).base(), result.end()); - result.erase(result.begin(), std::find_if(result.begin(), result.end(), [delimiter](char ch) - { - return ch != delimiter; - })); - return result; - } + std::string StringHelpers::trim(const std::string& s, char delimiter) + { + if(s.empty()) + { + return s; + } + std::string result{ s }; + result.erase(std::find_if(result.rbegin(), result.rend(), [delimiter](char ch) + { + return ch != delimiter; + }).base(), result.end()); + result.erase(result.begin(), std::find_if(result.begin(), result.end(), [delimiter](char ch) + { + return ch != delimiter; + })); + return result; + } } \ No newline at end of file diff --git a/src/update/updater.cpp b/src/update/updater.cpp index f8fb0f3..1f72616 100644 --- a/src/update/updater.cpp +++ b/src/update/updater.cpp @@ -17,29 +17,25 @@ using namespace Nickvision::Filesystem; namespace Nickvision::Update { - Updater::Updater(std::string githubRepoUrl) - : m_latestStableReleaseId{ -1 }, - m_latestPreviewReleaseId{ -1 } - { - if (!WebHelpers::isValidWebsite(githubRepoUrl)) - { - githubRepoUrl = Aura::getActive().getAppInfo().getSourceRepo(); - if (!WebHelpers::isValidWebsite(githubRepoUrl)) - { - throw std::invalid_argument("The source repo of the active Aura::AppInfo is invalid."); - } - } - try - { - std::vector fields{ StringHelpers::split(githubRepoUrl, "/") }; - m_repoOwner = fields[3]; - m_repoName = fields[4]; - } - catch (...) - { - throw std::invalid_argument("The url is not a valid GitHub repo."); - } - } + Updater::Updater(std::string githubRepoUrl) + : m_latestStableReleaseId{ -1 }, + m_latestPreviewReleaseId{ -1 } + { + if(githubRepoUrl.empty()) + { + throw std::invalid_argument("The url is not a valid formatted GitHub repo url."); + } + try + { + std::vector fields{ StringHelpers::split(githubRepoUrl, "/") }; + m_repoOwner = fields[3]; + m_repoName = fields[4]; + } + catch (...) + { + throw std::invalid_argument("The url is not a valid formatted GitHub repo url."); + } + } Updater::Updater(const Updater& u) { @@ -59,53 +55,53 @@ namespace Nickvision::Update m_latestPreviewReleaseId = std::move(u.m_latestPreviewReleaseId); } - Version Updater::fetchCurrentStableVersion() - { - return fetchCurrentVersion(VersionType::Stable); - } + Version Updater::fetchCurrentStableVersion() + { + return fetchCurrentVersion(VersionType::Stable); + } - Version Updater::fetchCurrentPreviewVersion() - { - return fetchCurrentVersion(VersionType::Preview); - } + Version Updater::fetchCurrentPreviewVersion() + { + return fetchCurrentVersion(VersionType::Preview); + } #ifdef _WIN32 - bool Updater::windowsUpdate(VersionType versionType) - { - std::lock_guard lock{ m_mutex }; - if (versionType == VersionType::Stable ? m_latestStableReleaseId == -1 : m_latestPreviewReleaseId == -1) - { - return false; - } - std::string release{ WebHelpers::fetchJsonString("https://api.github.com/repos/" + m_repoOwner + "/" + m_repoName + "/releases/" + std::to_string(versionType == VersionType::Stable ? m_latestStableReleaseId : m_latestPreviewReleaseId)) }; - if (!release.empty()) - { - Json::Value root; - Json::Reader reader; - if (reader.parse(release, root, false)) - { - for (const Json::Value& asset : root.get("assets", {})) - { - std::string name{ asset.get("name", "").asString() }; - if (StringHelpers::toLower(name).find("setup.exe") != std::string::npos) - { - std::filesystem::path setup{ UserDirectories::getApplicationCache() / name }; - if (WebHelpers::downloadFile(asset.get("browser_download_url", "").asString(), setup)) - { - std::string cmd{ "\"" + setup.string() + "\"" }; - if ((INT_PTR)ShellExecuteA(nullptr, "open", cmd.c_str(), nullptr, nullptr, SW_SHOWDEFAULT) > 32) - { - std::exit(0); - return true; - } - return false; - } - } - } - } - } - return false; - } + bool Updater::windowsUpdate(VersionType versionType) + { + std::lock_guard lock{ m_mutex }; + if (versionType == VersionType::Stable ? m_latestStableReleaseId == -1 : m_latestPreviewReleaseId == -1) + { + return false; + } + std::string release{ WebHelpers::fetchJsonString("https://api.github.com/repos/" + m_repoOwner + "/" + m_repoName + "/releases/" + std::to_string(versionType == VersionType::Stable ? m_latestStableReleaseId : m_latestPreviewReleaseId)) }; + if (!release.empty()) + { + Json::Value root; + Json::Reader reader; + if (reader.parse(release, root, false)) + { + for (const Json::Value& asset : root.get("assets", {})) + { + std::string name{ asset.get("name", "").asString() }; + if (StringHelpers::toLower(name).find("setup.exe") != std::string::npos) + { + std::filesystem::path setup{ UserDirectories::getApplicationCache() / name }; + if (WebHelpers::downloadFile(asset.get("browser_download_url", "").asString(), setup)) + { + std::string cmd{ "\"" + setup.string() + "\"" }; + if ((INT_PTR)ShellExecuteA(nullptr, "open", cmd.c_str(), nullptr, nullptr, SW_SHOWDEFAULT) > 32) + { + std::exit(0); + return true; + } + return false; + } + } + } + } + } + return false; + } #endif Updater& Updater::operator=(const Updater& u) @@ -136,36 +132,36 @@ namespace Nickvision::Update return *this; } - Version Updater::fetchCurrentVersion(VersionType versionType) - { - std::lock_guard lock{ m_mutex }; - std::string releases{ WebHelpers::fetchJsonString("https://api.github.com/repos/" + m_repoOwner + "/" + m_repoName + "/releases") }; - if (!releases.empty()) - { - Json::Value root; - Json::Reader reader; - if (reader.parse(releases, root, false)) - { - for (const Json::Value& release : root) - { - std::string version{ release.get("tag_name", "NULL").asString() }; - if (version == "NULL") - { - return {}; - } - if (versionType == VersionType::Stable && version.find('-') == std::string::npos) - { - m_latestStableReleaseId = release.get("id", -1).asInt(); - return version; - } - if (versionType == VersionType::Preview && version.find('-') != std::string::npos) - { - m_latestPreviewReleaseId = release.get("id", -1).asInt(); - return version; - } - } - } - } - return {}; - } + Version Updater::fetchCurrentVersion(VersionType versionType) + { + std::lock_guard lock{ m_mutex }; + std::string releases{ WebHelpers::fetchJsonString("https://api.github.com/repos/" + m_repoOwner + "/" + m_repoName + "/releases") }; + if (!releases.empty()) + { + Json::Value root; + Json::Reader reader; + if (reader.parse(releases, root, false)) + { + for (const Json::Value& release : root) + { + std::string version{ release.get("tag_name", "NULL").asString() }; + if (version == "NULL") + { + return {}; + } + if (versionType == VersionType::Stable && version.find('-') == std::string::npos) + { + m_latestStableReleaseId = release.get("id", -1).asInt(); + return version; + } + if (versionType == VersionType::Preview && version.find('-') != std::string::npos) + { + m_latestPreviewReleaseId = release.get("id", -1).asInt(); + return version; + } + } + } + } + return {}; + } } \ No newline at end of file diff --git a/tests/updatertests.cpp b/tests/updatertests.cpp index f99d1d9..f1e6927 100644 --- a/tests/updatertests.cpp +++ b/tests/updatertests.cpp @@ -10,5 +10,5 @@ TEST(UpdaterTests, ParabolicStableUpdate) Version stable{ updater.fetchCurrentStableVersion() }; ASSERT_TRUE(!stable.empty()); ASSERT_TRUE(stable.getVersionType() == VersionType::Stable); - ASSERT_TRUE(stable >= Version("2023.11.1")); + ASSERT_TRUE(stable >= Version("2023.12.0")); } \ No newline at end of file From c8742c6d08801af83aef6a60428cca26fa0200f2 Mon Sep 17 00:00:00 2001 From: Nick Logozzo Date: Mon, 29 Jan 2024 17:13:10 -0500 Subject: [PATCH 04/10] Fix Header File Spacing --- docs/events.md | 4 + include/app/appinfo.h | 424 +++++++++--------- include/app/configurationbase.h | 76 ++-- include/enumflags.h | 14 +- include/events/event.h | 256 +++++------ include/events/eventargs.h | 22 +- include/events/parameventargs.h | 52 +-- include/filesystem/fileaction.h | 20 +- .../filesystem/filesystemchangedeventargs.h | 52 +-- include/filesystem/filesystemwatcher.h | 156 +++---- include/filesystem/systemdirectories.h | 30 +- include/filesystem/userdirectories.h | 160 +++---- include/filesystem/watcherflags.h | 26 +- include/helpers/webhelpers.h | 52 +-- include/keyring/credential.h | 206 ++++----- include/keyring/credentialcheckstatus.h | 22 +- include/keyring/keyring.h | 158 +++---- include/keyring/keyringdialogcontroller.h | 152 +++---- include/keyring/passwordcontent.h | 22 +- include/keyring/passwordgenerator.h | 72 +-- include/keyring/store.h | 210 ++++----- include/keyring/systemcredentials.h | 60 +-- include/localization/documentation.h | 16 +- include/localization/gettext.h | 54 +-- include/network/networkmonitor.h | 87 ++-- include/network/networkstate.h | 18 +- .../network/networkstatechangedeventargs.h | 38 +- .../notifications/notificationsenteventargs.h | 80 ++-- include/notifications/notificationseverity.h | 20 +- include/notifications/notifyicon.h | 158 +++---- include/notifications/notifyiconmenu.h | 274 +++++------ include/notifications/shellnotification.h | 32 +- .../shellnotificationsenteventargs.h | 46 +- include/taskbar/progressstate.h | 22 +- include/taskbar/taskbaritem.h | 190 ++++---- include/update/version.h | 228 +++++----- include/update/versiontype.h | 16 +- 37 files changed, 1763 insertions(+), 1762 deletions(-) diff --git a/docs/events.md b/docs/events.md index 964240d..b65bac0 100644 --- a/docs/events.md +++ b/docs/events.md @@ -52,6 +52,10 @@ Path: `Nickvision::Events::Event` void operator-=(const std::function& handler) ``` - Accepts: A `std::function` with signature `void handler(const T&)` to remove as a callback for the event, handler. +- ```cpp + void operator()(const T& param) + ``` + - Accepts: A `T` object to pass as a parameter, param, as all registered callbacks are called on this event. - ```cpp Event& operator=(const Event& e) ``` diff --git a/include/app/appinfo.h b/include/app/appinfo.h index 1ca113b..10202aa 100644 --- a/include/app/appinfo.h +++ b/include/app/appinfo.h @@ -8,220 +8,220 @@ namespace Nickvision::App { - /** - * @brief A model for the information about an application. - */ - class AppInfo - { - public: - /** - * @brief Constructs an AppInfo. - */ - AppInfo() = default; - /** - * @brief Gets the application id. - * @return The application id - */ - const std::string& getId() const; - /** - * @brief Sets the application id. - * @param id The application id - */ - void setId(const std::string& id); - /** - * @brief Gets the application name. - * @return The application name - */ - const std::string& getName() const; - /** - * @brief Sets the application name. - * @param name The application name - */ - void setName(const std::string& name); - /** - * @brief Gets the application short name. - * @return The application short name - */ - const std::string& getShortName() const; - /** - * @brief Sets the application short name. - * @param shortName The application short name - */ - void setShortName(const std::string& shortName); - /** - * @brief Gets the application English short name. - * @return The application English short name - */ - const std::string& getEnglishShortName() const; - /** - * @brief Sets the application English short name. - * @param englishShortName The application English short name - */ - void setEnglishShortName(const std::string& englishShortName); - /** - * @brief Gets the application description. - * @return The application description - */ - const std::string& getDescription() const; - /** - * @brief Sets the application description. - * @param description The application description - */ - void setDescription(const std::string& description); - /** - * @brief Gets the application version. - * @return The application version - */ - const Update::Version& getVersion() const; - /** - * @brief Sets the application version. - * @param version The application version - */ - void setVersion(const Update::Version& version); - /** - * @brief Gets the application changelog. - * @return The application changelog - */ - const std::string& getChangelog() const; - /** - * @brief Sets the application changelog. - * @param changelog The application changelog - */ - void setChangelog(const std::string& changelog); - /** - * @brief Gets the application changelog in HTML form - * @return The application changelog in HTML - */ - const std::string& getHtmlChangelog() const; - /** - * @brief Gets the application source repo url - * @return The application source repo url - */ - const std::string& getSourceRepo() const; - /** - * @brief Sets the application source repo url - * @param sourceRepo The application source repo url - * @return True if the new source repo was set, else false - * @return A false return value means that the sourceRepo param was not a valid formatted URL - */ - bool setSourceRepo(const std::string& sourceRepo); - /** - * @brief Gets the application issue tracker url - * @return The application issue tracker url - */ - const std::string& getIssueTracker() const; - /** - * @brief Sets the application issue tracker url - * @param issueTracker The application issue tracker url - * @return True if the new issue tracker was set, else false - * @return A false return value means that the issueTracker param was not a valid formatted URL - */ - bool setIssueTracker(const std::string& issueTracker); - /** - * @brief Gets the application support url - * @return The application support url - */ - const std::string& getSupportUrl() const; - /** - * @brief Sets the application support url - * @param supportUrl The application support url - * @return True if the new support url was set, else false - * @return A false return value means that the supportUrl param was not a valid formatted URL - */ - bool setSupportUrl(const std::string& supportUrl); - /** - * @brief Gets the application html docs store url - * @return The application html docs store url - */ - const std::string& getHtmlDocsStore() const; - /** - * @brief Sets the application html docs store url - * @param supportUrl The application html docs store url - */ - void setHtmlDocsStore(const std::string& htmlDocsStore); - /** - * @brief Gets the extra links for the application - * @return The extra links for the application - */ - std::map& getExtraLinks(); - /** - * @brief Gets the extra links for the application - * @return The extra links for the application - */ - const std::map& getExtraLinks() const; - /** - * @brief Gets the application developers - * @return The application developers - */ - std::map& getDevelopers(); - /** - * @brief Gets the application developers - * @return The application developers - */ - const std::map& getDevelopers() const; - /** - * @brief Gets the application designers - * @return The application designers - */ - std::map& getDesigners(); - /** - * @brief Gets the application designers - * @return The application designers - */ - const std::map& getDesigners() const; - /** - * @brief Gets the application artists - * @return The application artists - */ - std::map& getArtists(); - /** - * @brief Gets the application artists - * @return The application artists - */ - const std::map& getArtists() const; - /** - * @brief Gets the application translator credits - * @return The application translator credits - */ - const std::string& getTranslatorCredits() const; - /** - * @brief Sets the application translator credits - * @param translatorCredits The application translator credits - */ - void setTranslatorCredits(const std::string& translatorCredits); - /** - * @brief Gets the list of translator names - * @return The application translator credits - */ - std::vector getTranslatorNames() const; + /** + * @brief A model for the information about an application. + */ + class AppInfo + { + public: + /** + * @brief Constructs an AppInfo. + */ + AppInfo() = default; + /** + * @brief Gets the application id. + * @return The application id + */ + const std::string& getId() const; + /** + * @brief Sets the application id. + * @param id The application id + */ + void setId(const std::string& id); + /** + * @brief Gets the application name. + * @return The application name + */ + const std::string& getName() const; + /** + * @brief Sets the application name. + * @param name The application name + */ + void setName(const std::string& name); + /** + * @brief Gets the application short name. + * @return The application short name + */ + const std::string& getShortName() const; + /** + * @brief Sets the application short name. + * @param shortName The application short name + */ + void setShortName(const std::string& shortName); + /** + * @brief Gets the application English short name. + * @return The application English short name + */ + const std::string& getEnglishShortName() const; + /** + * @brief Sets the application English short name. + * @param englishShortName The application English short name + */ + void setEnglishShortName(const std::string& englishShortName); + /** + * @brief Gets the application description. + * @return The application description + */ + const std::string& getDescription() const; + /** + * @brief Sets the application description. + * @param description The application description + */ + void setDescription(const std::string& description); + /** + * @brief Gets the application version. + * @return The application version + */ + const Update::Version& getVersion() const; + /** + * @brief Sets the application version. + * @param version The application version + */ + void setVersion(const Update::Version& version); + /** + * @brief Gets the application changelog. + * @return The application changelog + */ + const std::string& getChangelog() const; + /** + * @brief Sets the application changelog. + * @param changelog The application changelog + */ + void setChangelog(const std::string& changelog); + /** + * @brief Gets the application changelog in HTML form + * @return The application changelog in HTML + */ + const std::string& getHtmlChangelog() const; + /** + * @brief Gets the application source repo url + * @return The application source repo url + */ + const std::string& getSourceRepo() const; + /** + * @brief Sets the application source repo url + * @param sourceRepo The application source repo url + * @return True if the new source repo was set, else false + * @return A false return value means that the sourceRepo param was not a valid formatted URL + */ + bool setSourceRepo(const std::string& sourceRepo); + /** + * @brief Gets the application issue tracker url + * @return The application issue tracker url + */ + const std::string& getIssueTracker() const; + /** + * @brief Sets the application issue tracker url + * @param issueTracker The application issue tracker url + * @return True if the new issue tracker was set, else false + * @return A false return value means that the issueTracker param was not a valid formatted URL + */ + bool setIssueTracker(const std::string& issueTracker); + /** + * @brief Gets the application support url + * @return The application support url + */ + const std::string& getSupportUrl() const; + /** + * @brief Sets the application support url + * @param supportUrl The application support url + * @return True if the new support url was set, else false + * @return A false return value means that the supportUrl param was not a valid formatted URL + */ + bool setSupportUrl(const std::string& supportUrl); + /** + * @brief Gets the application html docs store url + * @return The application html docs store url + */ + const std::string& getHtmlDocsStore() const; + /** + * @brief Sets the application html docs store url + * @param supportUrl The application html docs store url + */ + void setHtmlDocsStore(const std::string& htmlDocsStore); + /** + * @brief Gets the extra links for the application + * @return The extra links for the application + */ + std::map& getExtraLinks(); + /** + * @brief Gets the extra links for the application + * @return The extra links for the application + */ + const std::map& getExtraLinks() const; + /** + * @brief Gets the application developers + * @return The application developers + */ + std::map& getDevelopers(); + /** + * @brief Gets the application developers + * @return The application developers + */ + const std::map& getDevelopers() const; + /** + * @brief Gets the application designers + * @return The application designers + */ + std::map& getDesigners(); + /** + * @brief Gets the application designers + * @return The application designers + */ + const std::map& getDesigners() const; + /** + * @brief Gets the application artists + * @return The application artists + */ + std::map& getArtists(); + /** + * @brief Gets the application artists + * @return The application artists + */ + const std::map& getArtists() const; + /** + * @brief Gets the application translator credits + * @return The application translator credits + */ + const std::string& getTranslatorCredits() const; + /** + * @brief Sets the application translator credits + * @param translatorCredits The application translator credits + */ + void setTranslatorCredits(const std::string& translatorCredits); + /** + * @brief Gets the list of translator names + * @return The application translator credits + */ + std::vector getTranslatorNames() const; - private: - std::string m_id; - std::string m_name; - std::string m_shortName; - std::string m_englishShortName; - std::string m_description; - Update::Version m_version; - std::string m_changelog; - std::string m_htmlChangelog; - std::string m_sourceRepo; - std::string m_issueTracker; - std::string m_supportUrl; - std::string m_htmlDocsStore; - std::map m_extraLinks; - std::map m_developers; - std::map m_designers; - std::map m_artists; - std::string m_translatorCredits; + private: + std::string m_id; + std::string m_name; + std::string m_shortName; + std::string m_englishShortName; + std::string m_description; + Update::Version m_version; + std::string m_changelog; + std::string m_htmlChangelog; + std::string m_sourceRepo; + std::string m_issueTracker; + std::string m_supportUrl; + std::string m_htmlDocsStore; + std::map m_extraLinks; + std::map m_developers; + std::map m_designers; + std::map m_artists; + std::string m_translatorCredits; - public: - /** - * @brief Converts a map of URLs to a vector - * @param urls The map of URLs - * @return The vector of URLs - */ - static std::vector convertUrlMapToVector(const std::map& urls); - }; + public: + /** + * @brief Converts a map of URLs to a vector + * @param urls The map of URLs + * @return The vector of URLs + */ + static std::vector convertUrlMapToVector(const std::map& urls); + }; } #endif // APPINFO_H diff --git a/include/app/configurationbase.h b/include/app/configurationbase.h index 4ecb762..3b5bf1c 100644 --- a/include/app/configurationbase.h +++ b/include/app/configurationbase.h @@ -8,46 +8,46 @@ namespace Nickvision::App { - /** - * A base class for configuration files. - */ - class ConfigurationBase - { - public: - /** - * @brief Constructs a ConfigurationBase, loading the file from disk. - * @param key The key of the config file - * @throw std::invalid_argument Thrown if key is empty - */ - ConfigurationBase(const std::string& key); - /** - * @brief Destructs a ConfigurationBase. - */ - virtual ~ConfigurationBase() = default; - /** - * Gets the key of the config file. - * @return The key of the config file - */ - const std::string& getKey() const; - /** - * @brief Gets the Saved event. - * @return The Saved event - */ - Events::Event& saved(); - /** - * @brief Saves the config file to disk. - * @return True if saved to disk, else false - */ - bool save(); + /** + * A base class for configuration files. + */ + class ConfigurationBase + { + public: + /** + * @brief Constructs a ConfigurationBase, loading the file from disk. + * @param key The key of the config file + * @throw std::invalid_argument Thrown if key is empty + */ + ConfigurationBase(const std::string& key); + /** + * @brief Destructs a ConfigurationBase. + */ + virtual ~ConfigurationBase() = default; + /** + * Gets the key of the config file. + * @return The key of the config file + */ + const std::string& getKey() const; + /** + * @brief Gets the Saved event. + * @return The Saved event + */ + Events::Event& saved(); + /** + * @brief Saves the config file to disk. + * @return True if saved to disk, else false + */ + bool save(); - protected: - Json::Value m_json; + protected: + Json::Value m_json; - private: - std::string m_key; - std::filesystem::path m_path; - Events::Event m_saved; - }; + private: + std::string m_key; + std::filesystem::path m_path; + Events::Event m_saved; + }; } #endif //CONFIGURATIONBASE_H \ No newline at end of file diff --git a/include/enumflags.h b/include/enumflags.h index ac55ac4..73d0356 100644 --- a/include/enumflags.h +++ b/include/enumflags.h @@ -7,31 +7,31 @@ static_assert(std::is_enum_v == true); \ inline T operator~(T a) \ { \ - return (T)~(int)a; \ + return (T)~(int)a; \ } \ inline T operator|(T a, T b) \ { \ - return (T)((int)a | (int)b); \ + return (T)((int)a | (int)b); \ } \ inline T operator&(T a, T b) \ { \ - return (T)((int)a & (int)b); \ + return (T)((int)a & (int)b); \ } \ inline T operator^(T a, T b) \ { \ - return (T)((int)a ^ (int)b); \ + return (T)((int)a ^ (int)b); \ } \ inline T& operator|=(T& a, T b) \ { \ - return (T&)((int&)a |= (int)b); \ + return (T&)((int&)a |= (int)b); \ } \ inline T& operator&=(T& a, T b) \ { \ - return (T&)((int&)a &= (int)b); \ + return (T&)((int&)a &= (int)b); \ } \ inline T& operator^=(T& a, T b) \ { \ - return (T&)((int&)a ^= (int)b); \ + return (T&)((int&)a ^= (int)b); \ } #endif //ENUMFLAGS_H \ No newline at end of file diff --git a/include/events/event.h b/include/events/event.h index 929ed1f..75b5b16 100644 --- a/include/events/event.h +++ b/include/events/event.h @@ -10,136 +10,136 @@ namespace Nickvision::Events { - template - concept DerivedEventArgs = std::is_base_of_v; + template + concept DerivedEventArgs = std::is_base_of_v; - /** - * @brief An event that can have handlers subscribe to it, which in turn will be called when the event is invoked. - * @tparam T Derived type of EventArgs - */ - template - class Event - { - public: - /** - * @brief Constructs an Event. - */ - Event() = default; - /** - * @brief Constructs an Event via copy. - * @param e The object to copy - */ - Event(const Event& e) - { - std::lock_guard lock{ e.m_mutex }; - m_handlers = e.m_handlers; - } - /** - * @brief Constructs an Event via move. - * @param e The object to move - */ - Event(Event&& e) noexcept - { - std::lock_guard lock{ e.m_mutex }; - m_handlers = std::move(e.m_handlers); - } - /** - * @brief Subscribes a handler to the event. - * @param handler The handler function - */ - void subscribe(const std::function& handler) - { - std::lock_guard lock{ m_mutex }; - m_handlers.push_back(handler); - } - /** - * @brief Unsubscribes a handler from the event. - * @param handler The handler function - */ - void unsubscribe(const std::function& handler) - { - std::lock_guard lock{ m_mutex }; - if (m_handlers.size() == 0) - { - return; - } - auto it{ std::find(m_handlers.begin(), m_handlers.end(), handler) }; - if (it != m_handlers.end()) - { - m_handlers.erase(it); - } - } - /** - * @brief Invokes the event, calling all handlers. - * @param param The parameter to pass to the handlers - */ - void invoke(const T& param) const - { - std::lock_guard lock{ m_mutex }; - for (const std::function& handler : m_handlers) - { - handler(param); - } - } - /** - * @brief Subscribes a handler to the event. - * @param handler The handler function - */ - void operator+=(const std::function& handler) - { - subscribe(handler); - } - /** - * @brief Unsubscribes a handler from the event. - * @param handler The handler function - */ - void operator-=(const std::function& handler) - { - unsubscribe(handler); - } - /** - * @brief Invokes the event, calling all handlers. - * @param param The parameter to pass to the handlers - */ - void operator()(const T& param) - { - invoke(param); - } - /** - * @brief Copies an Event. - * @param e The Event to copy - * @return this - */ - Event& operator=(const Event& e) - { - if (this != &e) - { - std::lock_guard lock{ m_mutex }; - std::lock_guard lock2{ e.m_mutex }; - m_handlers = e.m_handlers; - } - return *this; - } - /** - * @brief Moves an Event. - * @param e The Event to move - * @return this - */ - Event& operator=(Event&& e) noexcept - { - if (this != &e) - { - std::lock_guard lock{ m_mutex }; - std::lock_guard lock2{ e.m_mutex }; - m_handlers = std::move(e.m_handlers); - } - return *this; - } + /** + * @brief An event that can have handlers subscribe to it, which in turn will be called when the event is invoked. + * @tparam T Derived type of EventArgs + */ + template + class Event + { + public: + /** + * @brief Constructs an Event. + */ + Event() = default; + /** + * @brief Constructs an Event via copy. + * @param e The object to copy + */ + Event(const Event& e) + { + std::lock_guard lock{ e.m_mutex }; + m_handlers = e.m_handlers; + } + /** + * @brief Constructs an Event via move. + * @param e The object to move + */ + Event(Event&& e) noexcept + { + std::lock_guard lock{ e.m_mutex }; + m_handlers = std::move(e.m_handlers); + } + /** + * @brief Subscribes a handler to the event. + * @param handler The handler function + */ + void subscribe(const std::function& handler) + { + std::lock_guard lock{ m_mutex }; + m_handlers.push_back(handler); + } + /** + * @brief Unsubscribes a handler from the event. + * @param handler The handler function + */ + void unsubscribe(const std::function& handler) + { + std::lock_guard lock{ m_mutex }; + if (m_handlers.size() == 0) + { + return; + } + auto it{ std::find(m_handlers.begin(), m_handlers.end(), handler) }; + if (it != m_handlers.end()) + { + m_handlers.erase(it); + } + } + /** + * @brief Invokes the event, calling all handlers. + * @param param The parameter to pass to the handlers + */ + void invoke(const T& param) const + { + std::lock_guard lock{ m_mutex }; + for (const std::function& handler : m_handlers) + { + handler(param); + } + } + /** + * @brief Subscribes a handler to the event. + * @param handler The handler function + */ + void operator+=(const std::function& handler) + { + subscribe(handler); + } + /** + * @brief Unsubscribes a handler from the event. + * @param handler The handler function + */ + void operator-=(const std::function& handler) + { + unsubscribe(handler); + } + /** + * @brief Invokes the event, calling all handlers. + * @param param The parameter to pass to the handlers + */ + void operator()(const T& param) + { + invoke(param); + } + /** + * @brief Copies an Event. + * @param e The Event to copy + * @return this + */ + Event& operator=(const Event& e) + { + if (this != &e) + { + std::lock_guard lock{ m_mutex }; + std::lock_guard lock2{ e.m_mutex }; + m_handlers = e.m_handlers; + } + return *this; + } + /** + * @brief Moves an Event. + * @param e The Event to move + * @return this + */ + Event& operator=(Event&& e) noexcept + { + if (this != &e) + { + std::lock_guard lock{ m_mutex }; + std::lock_guard lock2{ e.m_mutex }; + m_handlers = std::move(e.m_handlers); + } + return *this; + } - private: - mutable std::mutex m_mutex; - std::vector> m_handlers; - }; + private: + mutable std::mutex m_mutex; + std::vector> m_handlers; + }; } #endif //EVENT_H \ No newline at end of file diff --git a/include/events/eventargs.h b/include/events/eventargs.h index d5e83c0..9850a72 100644 --- a/include/events/eventargs.h +++ b/include/events/eventargs.h @@ -3,17 +3,17 @@ namespace Nickvision::Events { - /** - * @brief A base class for event arguments. - */ - class EventArgs - { - public: - /** - * @brief Constructs an EventArgs. - */ - EventArgs() = default; - }; + /** + * @brief A base class for event arguments. + */ + class EventArgs + { + public: + /** + * @brief Constructs an EventArgs. + */ + EventArgs() = default; + }; } #endif //EVENTARGS_H \ No newline at end of file diff --git a/include/events/parameventargs.h b/include/events/parameventargs.h index a4c0e89..5b956a1 100644 --- a/include/events/parameventargs.h +++ b/include/events/parameventargs.h @@ -6,38 +6,38 @@ namespace Nickvision::Events { - /** - * @brief An event argument that contains a single parameter. + /** + * @brief An event argument that contains a single parameter. * @brief T must be copy and move constructible. - */ - template - class ParamEventArgs : public EventArgs - { + */ + template + class ParamEventArgs : public EventArgs + { static_assert(std::is_copy_constructible_v == true); static_assert(std::is_move_constructible_v == true); - public: - /** - * @brief Constructs a ParamEventArgs. - * @param param The parameter to store in the event args - */ - ParamEventArgs(const T& param) - : m_param{ param } - { + public: + /** + * @brief Constructs a ParamEventArgs. + * @param param The parameter to store in the event args + */ + ParamEventArgs(const T& param) + : m_param{ param } + { - } - /** - * @brief Gets the param stored in the event args. - * @return The param stored - */ - const T& getParam() const - { - return m_param; - } + } + /** + * @brief Gets the param stored in the event args. + * @return The param stored + */ + const T& getParam() const + { + return m_param; + } - private: - T m_param; - }; + private: + T m_param; + }; } #endif //PARAMEVENTARGS_H \ No newline at end of file diff --git a/include/filesystem/fileaction.h b/include/filesystem/fileaction.h index b2dcad7..cf952d6 100644 --- a/include/filesystem/fileaction.h +++ b/include/filesystem/fileaction.h @@ -3,16 +3,16 @@ namespace Nickvision::Filesystem { - /** - * @brief Actions that cause a file system object to change. - */ - enum class FileAction - { - Added = 1, - Removed, - Modified, - Renamed - }; + /** + * @brief Actions that cause a file system object to change. + */ + enum class FileAction + { + Added = 1, + Removed, + Modified, + Renamed + }; } #endif //FILEACTION_H \ No newline at end of file diff --git a/include/filesystem/filesystemchangedeventargs.h b/include/filesystem/filesystemchangedeventargs.h index e37d8cf..802b6dc 100644 --- a/include/filesystem/filesystemchangedeventargs.h +++ b/include/filesystem/filesystemchangedeventargs.h @@ -7,33 +7,33 @@ namespace Nickvision::Filesystem { - /** - * @brief Event args for when a file system object is changed. - */ - class FileSystemChangedEventArgs : public Events::EventArgs - { - public: - /** - * @brief Constructs a FileSystemChangedEventArgs. - * @param path The path of the file/folder that changed - * @param why The action that caused the file system object to change - */ - FileSystemChangedEventArgs(const std::filesystem::path& path, FileAction why); - /** - * @brief Gets the path of the changed file system object system object. - * @return The path of the changed file/folder - */ - const std::filesystem::path& getPath() const; - /** - * @brief Gets the action that caused the file system object to change. - * @return The action that caused the file system object to change - */ - FileAction getWhy() const; + /** + * @brief Event args for when a file system object is changed. + */ + class FileSystemChangedEventArgs : public Events::EventArgs + { + public: + /** + * @brief Constructs a FileSystemChangedEventArgs. + * @param path The path of the file/folder that changed + * @param why The action that caused the file system object to change + */ + FileSystemChangedEventArgs(const std::filesystem::path& path, FileAction why); + /** + * @brief Gets the path of the changed file system object system object. + * @return The path of the changed file/folder + */ + const std::filesystem::path& getPath() const; + /** + * @brief Gets the action that caused the file system object to change. + * @return The action that caused the file system object to change + */ + FileAction getWhy() const; - private: - std::filesystem::path m_path; - FileAction m_why; - }; + private: + std::filesystem::path m_path; + FileAction m_why; + }; } #endif //FILESYSTEMCHANGEDEVENTARGS_H \ No newline at end of file diff --git a/include/filesystem/filesystemwatcher.h b/include/filesystem/filesystemwatcher.h index ff38909..18d0aad 100644 --- a/include/filesystem/filesystemwatcher.h +++ b/include/filesystem/filesystemwatcher.h @@ -14,88 +14,88 @@ namespace Nickvision::Filesystem { - /** - * @brief A watcher of a file system folder. - */ - class FileSystemWatcher - { - public: - /** - * @brief Constructs a FileSystemWatcher. - * @param path The path of the folder to watch - * @param includeSubdirectories Whether or not to include subdirectories for the folder - * @param watcherFlags The flags of what to watch changes for - * @exception std::runtime_error Thrown if unable to initialize watcher - */ - FileSystemWatcher(const std::filesystem::path& path, bool includeSubdirectories, WatcherFlags watcherFlags = WatcherFlags::FileName | WatcherFlags::DirectoryName | WatcherFlags::Attributes | WatcherFlags::Size | WatcherFlags::LastWrite | WatcherFlags::LastAccess); - /** - * @brief Destructs a FileSystemWatcher. - */ - ~FileSystemWatcher(); - /** - * @brief Gets the path of the folder being watched. - * @return The path of the folder being watched - */ - const std::filesystem::path& getPath() const; - /** - * @brief Gets the flags of what to watch changes for. - * @return The flags of watched properties - */ - WatcherFlags getWatcherFlags() const; - /** - * @brief Gets whether or not subdirectories of the folder are watched. - * @return True if subdirectories watched, else false - */ - bool getIncludeSubdirectories() const; - /** - * @brief Gets the event for when a watched flag of the folder is changed. - * @return The changed event - */ - Events::Event& changed(); - /** - * @brief Gets whether or not a file extension is being watched. - * @param extension The file extension to check - * @return True if extension is being watched, else false - * @return True if list of extension filters is empty - */ - bool isExtensionWatched(const std::filesystem::path& extension); - /** - * @brief Adds an extension of a file to watch for changes in the folder. - * @param extension The file extension to add - * @return True if successful, else false - */ - bool addExtensionFilter(const std::filesystem::path& extension); - /** - * @brief Removes an extension of a file to watch for changes in the folder. - * @param extension The file extension to remove - * @return True if successful, else false - */ - bool removeExtensionFilter(const std::filesystem::path& extension); - /** - * @brief Clears all watched extension filters. This will cause all extensions to be implicitly watched. - * @return True if successful, else false - */ - bool clearExtensionFilters(); + /** + * @brief A watcher of a file system folder. + */ + class FileSystemWatcher + { + public: + /** + * @brief Constructs a FileSystemWatcher. + * @param path The path of the folder to watch + * @param includeSubdirectories Whether or not to include subdirectories for the folder + * @param watcherFlags The flags of what to watch changes for + * @exception std::runtime_error Thrown if unable to initialize watcher + */ + FileSystemWatcher(const std::filesystem::path& path, bool includeSubdirectories, WatcherFlags watcherFlags = WatcherFlags::FileName | WatcherFlags::DirectoryName | WatcherFlags::Attributes | WatcherFlags::Size | WatcherFlags::LastWrite | WatcherFlags::LastAccess); + /** + * @brief Destructs a FileSystemWatcher. + */ + ~FileSystemWatcher(); + /** + * @brief Gets the path of the folder being watched. + * @return The path of the folder being watched + */ + const std::filesystem::path& getPath() const; + /** + * @brief Gets the flags of what to watch changes for. + * @return The flags of watched properties + */ + WatcherFlags getWatcherFlags() const; + /** + * @brief Gets whether or not subdirectories of the folder are watched. + * @return True if subdirectories watched, else false + */ + bool getIncludeSubdirectories() const; + /** + * @brief Gets the event for when a watched flag of the folder is changed. + * @return The changed event + */ + Events::Event& changed(); + /** + * @brief Gets whether or not a file extension is being watched. + * @param extension The file extension to check + * @return True if extension is being watched, else false + * @return True if list of extension filters is empty + */ + bool isExtensionWatched(const std::filesystem::path& extension); + /** + * @brief Adds an extension of a file to watch for changes in the folder. + * @param extension The file extension to add + * @return True if successful, else false + */ + bool addExtensionFilter(const std::filesystem::path& extension); + /** + * @brief Removes an extension of a file to watch for changes in the folder. + * @param extension The file extension to remove + * @return True if successful, else false + */ + bool removeExtensionFilter(const std::filesystem::path& extension); + /** + * @brief Clears all watched extension filters. This will cause all extensions to be implicitly watched. + * @return True if successful, else false + */ + bool clearExtensionFilters(); - private: - /** - * @brief Runs the loop to watch a folder for changes. - */ - void watch(); - mutable std::mutex m_mutex; - std::filesystem::path m_path; - bool m_includeSubdirectories; - WatcherFlags m_watcherFlags; - Events::Event m_changed; - bool m_watching; - std::vector m_extensionFilters; - std::jthread m_watchThread; + private: + /** + * @brief Runs the loop to watch a folder for changes. + */ + void watch(); + mutable std::mutex m_mutex; + std::filesystem::path m_path; + bool m_includeSubdirectories; + WatcherFlags m_watcherFlags; + Events::Event m_changed; + bool m_watching; + std::vector m_extensionFilters; + std::jthread m_watchThread; #ifdef _WIN32 - HANDLE m_terminateEvent; + HANDLE m_terminateEvent; #elif defined(__linux__) - int m_notify; + int m_notify; #endif - }; + }; } #endif //FILESYSTEMWATCHER_H \ No newline at end of file diff --git a/include/filesystem/systemdirectories.h b/include/filesystem/systemdirectories.h index c68a7a0..6e8d75c 100644 --- a/include/filesystem/systemdirectories.h +++ b/include/filesystem/systemdirectories.h @@ -6,21 +6,21 @@ namespace Nickvision::Filesystem::SystemDirectories { - /* - * @brief Gets a list of directories from the PATH variable - * @return The list of directories from PATH - */ - std::vector getPath(); - /* - * @brief Gets a list of directories from the XDG_CONFIG_DIRS variable - * @return The list of directories from XDG_CONFIG_DIRS - */ - std::vector getConfig(); - /* - * @brief Gets a list of directories from the XDG_DATA_DIRS variable - * @return The list of directories from XDG_DATA_DIRS - */ - std::vector getData(); + /* + * @brief Gets a list of directories from the PATH variable + * @return The list of directories from PATH + */ + std::vector getPath(); + /* + * @brief Gets a list of directories from the XDG_CONFIG_DIRS variable + * @return The list of directories from XDG_CONFIG_DIRS + */ + std::vector getConfig(); + /* + * @brief Gets a list of directories from the XDG_DATA_DIRS variable + * @return The list of directories from XDG_DATA_DIRS + */ + std::vector getData(); } #endif //SYSTEMDIRECTORIES_H \ No newline at end of file diff --git a/include/filesystem/userdirectories.h b/include/filesystem/userdirectories.h index 84189fa..b1b65e0 100644 --- a/include/filesystem/userdirectories.h +++ b/include/filesystem/userdirectories.h @@ -5,86 +5,86 @@ namespace Nickvision::Filesystem::UserDirectories { - /* - * @brief Gets the user's home directory - * @return FOLDERID_Profile on Windows, $HOME on Linux - */ - std::filesystem::path getHome(); - /* - * @brief Gets the user's config directory - * @return FOLDERID_RoamingAppData on Windows, XDG_CONFIG_HOME on Linux - */ - std::filesystem::path getConfig(); - /* - * @brief Gets the applications's config directory - * @return getConfig() + Aura::getActive().getAppInfo().getName() - */ - std::filesystem::path getApplicationConfig(); - /* - * @brief Gets the user's cache directory - * @return FOLDERID_LocalAppData on Windows, XDG_CACHE_HOME on Linux - */ - std::filesystem::path getCache(); - /* - * @brief Gets the applications's cache directory - * @return getCache() + Aura::getActive().getAppInfo().getName() - */ - std::filesystem::path getApplicationCache(); - /* - * @brief Gets the user's local data directory - * @return FOLDERID_RoamingAppData on Windows, XDG_DATA_HOME on Linux - */ - std::filesystem::path getLocalData(); - /* - * @brief Gets the applications's local data directory - * @return getLocalData() + Aura::getActive().getAppInfo().getName() - */ - std::filesystem::path getApplicationLocalData(); - /* - * @brief Gets the user's runtime directory - * @return Empty path on Windows, XDG_RUNTIME_DIR on Linux - */ - std::filesystem::path getRuntime(); - /* - * @brief Gets the user's desktop directory - * @return FOLDERID_Desktop on Windows, XDG_DESKTOP_DIR on Linux - */ - std::filesystem::path getDesktop(); - /* - * @brief Gets the user's documents directory - * @return FOLDERID_Documents on Windows, XDG_DOCUMENTS_DIR on Linux - */ - std::filesystem::path getDocuments(); - /* - * @brief Gets the user's downloads directory - * @return FOLDERID_Downloads on Windows, XDG_DOWNLOAD_DIR on Linux - */ - std::filesystem::path getDownloads(); - /* - * @brief Gets the user's music directory - * @return FOLDERID_Music on Windows, XDG_MUSIC_DIR on Linux - */ - std::filesystem::path getMusic(); - /* - * @brief Gets the user's pictures directory - * @return FOLDERID_Pictures on Windows, XDG_PICTURES_DIR on Linux - */ - std::filesystem::path getPictures(); - /* - * @brief Gets the user's public share directory - * @return Empty path on Windows, XDG_PUBLICSHARE_DIR on Linux - */ - std::filesystem::path getPublicShare(); - /* - * @brief Gets the user's templates directory - * @return FOLDERID_Templates on Windows, XDG_TEMPLATES_DIR on Linux - */ - std::filesystem::path getTemplates(); - /* - * @brief Gets the user's videos directory - * @return FOLDERID_Videos on Windows, XDG_VIDEOS_DIR on Linux - */ - std::filesystem::path getVideos(); + /* + * @brief Gets the user's home directory + * @return FOLDERID_Profile on Windows, $HOME on Linux + */ + std::filesystem::path getHome(); + /* + * @brief Gets the user's config directory + * @return FOLDERID_RoamingAppData on Windows, XDG_CONFIG_HOME on Linux + */ + std::filesystem::path getConfig(); + /* + * @brief Gets the applications's config directory + * @return getConfig() + Aura::getActive().getAppInfo().getName() + */ + std::filesystem::path getApplicationConfig(); + /* + * @brief Gets the user's cache directory + * @return FOLDERID_LocalAppData on Windows, XDG_CACHE_HOME on Linux + */ + std::filesystem::path getCache(); + /* + * @brief Gets the applications's cache directory + * @return getCache() + Aura::getActive().getAppInfo().getName() + */ + std::filesystem::path getApplicationCache(); + /* + * @brief Gets the user's local data directory + * @return FOLDERID_RoamingAppData on Windows, XDG_DATA_HOME on Linux + */ + std::filesystem::path getLocalData(); + /* + * @brief Gets the applications's local data directory + * @return getLocalData() + Aura::getActive().getAppInfo().getName() + */ + std::filesystem::path getApplicationLocalData(); + /* + * @brief Gets the user's runtime directory + * @return Empty path on Windows, XDG_RUNTIME_DIR on Linux + */ + std::filesystem::path getRuntime(); + /* + * @brief Gets the user's desktop directory + * @return FOLDERID_Desktop on Windows, XDG_DESKTOP_DIR on Linux + */ + std::filesystem::path getDesktop(); + /* + * @brief Gets the user's documents directory + * @return FOLDERID_Documents on Windows, XDG_DOCUMENTS_DIR on Linux + */ + std::filesystem::path getDocuments(); + /* + * @brief Gets the user's downloads directory + * @return FOLDERID_Downloads on Windows, XDG_DOWNLOAD_DIR on Linux + */ + std::filesystem::path getDownloads(); + /* + * @brief Gets the user's music directory + * @return FOLDERID_Music on Windows, XDG_MUSIC_DIR on Linux + */ + std::filesystem::path getMusic(); + /* + * @brief Gets the user's pictures directory + * @return FOLDERID_Pictures on Windows, XDG_PICTURES_DIR on Linux + */ + std::filesystem::path getPictures(); + /* + * @brief Gets the user's public share directory + * @return Empty path on Windows, XDG_PUBLICSHARE_DIR on Linux + */ + std::filesystem::path getPublicShare(); + /* + * @brief Gets the user's templates directory + * @return FOLDERID_Templates on Windows, XDG_TEMPLATES_DIR on Linux + */ + std::filesystem::path getTemplates(); + /* + * @brief Gets the user's videos directory + * @return FOLDERID_Videos on Windows, XDG_VIDEOS_DIR on Linux + */ + std::filesystem::path getVideos(); } #endif //USERDIRECTORIES_H \ No newline at end of file diff --git a/include/filesystem/watcherflags.h b/include/filesystem/watcherflags.h index cf3efc4..cecfc7d 100644 --- a/include/filesystem/watcherflags.h +++ b/include/filesystem/watcherflags.h @@ -5,20 +5,20 @@ namespace Nickvision::Filesystem { - /** - * @brief Flags to describe properties of a file system object that can change. - */ - enum class WatcherFlags - { - FileName = 1, - DirectoryName = 2, - Attributes = 4, - Size = 8, - LastWrite = 16, - LastAccess = 32 - }; + /** + * @brief Flags to describe properties of a file system object that can change. + */ + enum class WatcherFlags + { + FileName = 1, + DirectoryName = 2, + Attributes = 4, + Size = 8, + LastWrite = 16, + LastAccess = 32 + }; - DEFINE_ENUM_FLAG_OPERATORS(WatcherFlags); + DEFINE_ENUM_FLAG_OPERATORS(WatcherFlags); } #endif \ No newline at end of file diff --git a/include/helpers/webhelpers.h b/include/helpers/webhelpers.h index 164b810..9529f38 100644 --- a/include/helpers/webhelpers.h +++ b/include/helpers/webhelpers.h @@ -8,33 +8,33 @@ namespace Nickvision::WebHelpers { - typedef std::function CurlProgressFunction; + typedef std::function CurlProgressFunction; - /** - * @brief Downloads a file to disk. - * @param url The url of the file to download - * @param path The path on disk to save the file - * @param progress An optional function to receive progress on the download \n - * std::function \n - * dltotal - The total number of bytes to be downloaded \n - * dlnow - The total number of bytes currently downloaded \n - * ultotal - The total number of bytes to be uploaded (will always be 0) \n - * ulnow - The total number of bytes currently uploaded (will always be 0) \n - * @param overwrite Whether or not to overwrite existing files on disk - */ - bool downloadFile(const std::string& url, const std::filesystem::path& path, const CurlProgressFunction& progress = {}, bool overwrite = true); - /** - * @brief Fetches a json string from a url. - * @param url The url of the json string - * @return The fetched json string - */ - std::string fetchJsonString(const std::string& url); - /** - * @brief Gets whether or not a url points to a valid website. - * @param url The url to check - * @return True if valid website, else false - */ - bool isValidWebsite(const std::string& url); + /** + * @brief Downloads a file to disk. + * @param url The url of the file to download + * @param path The path on disk to save the file + * @param progress An optional function to receive progress on the download \n + * std::function \n + * dltotal - The total number of bytes to be downloaded \n + * dlnow - The total number of bytes currently downloaded \n + * ultotal - The total number of bytes to be uploaded (will always be 0) \n + * ulnow - The total number of bytes currently uploaded (will always be 0) \n + * @param overwrite Whether or not to overwrite existing files on disk + */ + bool downloadFile(const std::string& url, const std::filesystem::path& path, const CurlProgressFunction& progress = {}, bool overwrite = true); + /** + * @brief Fetches a json string from a url. + * @param url The url of the json string + * @return The fetched json string + */ + std::string fetchJsonString(const std::string& url); + /** + * @brief Gets whether or not a url points to a valid website. + * @param url The url to check + * @return True if valid website, else false + */ + bool isValidWebsite(const std::string& url); } #endif //WEBHELPERS_H \ No newline at end of file diff --git a/include/keyring/credential.h b/include/keyring/credential.h index 9553818..78ff1a4 100644 --- a/include/keyring/credential.h +++ b/include/keyring/credential.h @@ -6,110 +6,110 @@ namespace Nickvision::Keyring { - /** - * @brief A model of a credential stored in a keyring. - */ - class Credential - { - public: - /** - * @brief Constructs a credential. - * @param id The id of the credential - * @param name The name of the credential - * @param uri The uri of the credential (can also be used as a comment for the Credential) - * @param username The username of the credential - * @param password The password of the credential - */ - Credential(int id, const std::string& name, const std::string& uri, const std::string& username, const std::string& password); - /** - * @brief Constructs a credential. - * @param name The name of the credential - * @param uri The uri of the credential - * @param username The username of the credential - * @param password The password of the credential - */ - Credential(const std::string& name, const std::string& uri, const std::string& username, const std::string& password); - /** - * @brief Gets the id of the credential - * @return The id of the credential - */ - int getId() const; - /** - * @brief Gets the name of the credential - * @return The name of the credential - */ - const std::string& getName() const; - /** - * @brief Sets the name of the credential - * @param name The name of the credential - */ - void setName(const std::string& name); - /** - * @brief Gets the uri of the credential (can also be used as a comment for the Credential) - * @return The uri of the credential - */ - const std::string& getUri() const; - /** - * @brief Sets the uri of the credential (can also be used as a comment for the Credential) - * @param uri The uri of the credential - */ - void setUri(const std::string& uri); - /** - * @brief Gets the username of the credential - * @return The username of the credential - */ - const std::string& getUsername() const; - /** - * @brief Sets the username of the credential - * @param username The username of the credential - */ - void setUsername(const std::string& username); - /** - * @brief Gets the password of the credential - * @return The password of the credential - */ - const std::string& getPassword() const; - /** - * @brief Sets the password of the credential - * @param password The password of the credential - */ - void setPassword(const std::string& password); - /** - * @brief Compares Credential objects via < operator - * @param compare The Credential object to compare too - * @return True if this < compare - */ - bool operator<(const Credential& compare) const; - /** - * @brief Compares Credential objects via > operator - * @param compare The Credential object to compare too - * @return True if this > compare - */ - bool operator>(const Credential& compare) const; - /** - * @brief Compares Credential objects via == operator - * @param compare The Credential object to compare too - * @return True if this == compare - */ - bool operator==(const Credential& compare) const; - /** - * @brief Compares Credential objects via != operator - * @param compare The Credential object to compare too - * @return True if this != compare - */ - bool operator!=(const Credential& compare) const; - /** - * @brief Outputs the Credential object - */ - friend std::ostream& operator<<(std::ostream& os, const Credential& credential); + /** + * @brief A model of a credential stored in a keyring. + */ + class Credential + { + public: + /** + * @brief Constructs a credential. + * @param id The id of the credential + * @param name The name of the credential + * @param uri The uri of the credential (can also be used as a comment for the Credential) + * @param username The username of the credential + * @param password The password of the credential + */ + Credential(int id, const std::string& name, const std::string& uri, const std::string& username, const std::string& password); + /** + * @brief Constructs a credential. + * @param name The name of the credential + * @param uri The uri of the credential + * @param username The username of the credential + * @param password The password of the credential + */ + Credential(const std::string& name, const std::string& uri, const std::string& username, const std::string& password); + /** + * @brief Gets the id of the credential + * @return The id of the credential + */ + int getId() const; + /** + * @brief Gets the name of the credential + * @return The name of the credential + */ + const std::string& getName() const; + /** + * @brief Sets the name of the credential + * @param name The name of the credential + */ + void setName(const std::string& name); + /** + * @brief Gets the uri of the credential (can also be used as a comment for the Credential) + * @return The uri of the credential + */ + const std::string& getUri() const; + /** + * @brief Sets the uri of the credential (can also be used as a comment for the Credential) + * @param uri The uri of the credential + */ + void setUri(const std::string& uri); + /** + * @brief Gets the username of the credential + * @return The username of the credential + */ + const std::string& getUsername() const; + /** + * @brief Sets the username of the credential + * @param username The username of the credential + */ + void setUsername(const std::string& username); + /** + * @brief Gets the password of the credential + * @return The password of the credential + */ + const std::string& getPassword() const; + /** + * @brief Sets the password of the credential + * @param password The password of the credential + */ + void setPassword(const std::string& password); + /** + * @brief Compares Credential objects via < operator + * @param compare The Credential object to compare too + * @return True if this < compare + */ + bool operator<(const Credential& compare) const; + /** + * @brief Compares Credential objects via > operator + * @param compare The Credential object to compare too + * @return True if this > compare + */ + bool operator>(const Credential& compare) const; + /** + * @brief Compares Credential objects via == operator + * @param compare The Credential object to compare too + * @return True if this == compare + */ + bool operator==(const Credential& compare) const; + /** + * @brief Compares Credential objects via != operator + * @param compare The Credential object to compare too + * @return True if this != compare + */ + bool operator!=(const Credential& compare) const; + /** + * @brief Outputs the Credential object + */ + friend std::ostream& operator<<(std::ostream& os, const Credential& credential); - private: - int m_id; - std::string m_name; - std::string m_uri; - std::string m_username; - std::string m_password; - }; + private: + int m_id; + std::string m_name; + std::string m_uri; + std::string m_username; + std::string m_password; + }; } #endif //CREDENTIAL_H \ No newline at end of file diff --git a/include/keyring/credentialcheckstatus.h b/include/keyring/credentialcheckstatus.h index cb39b38..c7deac9 100644 --- a/include/keyring/credentialcheckstatus.h +++ b/include/keyring/credentialcheckstatus.h @@ -5,18 +5,18 @@ namespace Nickvision::Keyring { - /** - * @brief Flags to describe the status of a validated credential - */ - enum class CredentialCheckStatus - { - Valid = 1, - EmptyName = 2, - EmptyUsernamePassword = 4, - InvalidUri = 8 - }; + /** + * @brief Flags to describe the status of a validated credential + */ + enum class CredentialCheckStatus + { + Valid = 1, + EmptyName = 2, + EmptyUsernamePassword = 4, + InvalidUri = 8 + }; - DEFINE_ENUM_FLAG_OPERATORS(CredentialCheckStatus); + DEFINE_ENUM_FLAG_OPERATORS(CredentialCheckStatus); } #endif //CREDENTIALCHECKSTATUS_H \ No newline at end of file diff --git a/include/keyring/keyring.h b/include/keyring/keyring.h index 337593b..303113e 100644 --- a/include/keyring/keyring.h +++ b/include/keyring/keyring.h @@ -9,87 +9,87 @@ namespace Nickvision::Keyring { - /** - * @brief A model of a keyring object for managing credentials. - */ - class Keyring - { - public: - /** - * @brief Gets the name of the keyring. - * @return The name of the keyring - */ - const std::string& getName() const; - /** - * @brief Gets all credentials in the keyring. - * @return The list of all credentials - */ - std::vector getAllCredentials() const; - /** - * @brief Gets the credential matching the provided id. - * @param id The id of the credential - * @return The credential matching the id, std::nullopt if no matching credential - */ - std::optional getCredential(int id) const; - /** - * @brief Gets the credentials containing the provided name. - * @param name The name - * @return The list of credentials matching the name - */ - std::vector getCredentials(const std::string& name) const; - /** - * @brief Adds a credential to the keyring. - * @param credential The Credential to add - * @return True if successful, else false - */ - bool addCredential(const Credential& credential); - /** - * @brief Updates a credential in the keyring. - * @param credential The Credential to update - * @return True if successful, else false - */ - bool updateCredential(const Credential& credential); - /** - * @brief Deletes a credential from the keyring. - * @param id The id of the credential to delete - * @return True if successful, else false - */ - bool deleteCredential(int id); - /** - * @brief Destroys the keyring and all of its data from disk. Once this method is called, the object should no longer be referenced, with or without success. - * @return True if successful, else false - */ - bool destroy(); + /** + * @brief A model of a keyring object for managing credentials. + */ + class Keyring + { + public: + /** + * @brief Gets the name of the keyring. + * @return The name of the keyring + */ + const std::string& getName() const; + /** + * @brief Gets all credentials in the keyring. + * @return The list of all credentials + */ + std::vector getAllCredentials() const; + /** + * @brief Gets the credential matching the provided id. + * @param id The id of the credential + * @return The credential matching the id, std::nullopt if no matching credential + */ + std::optional getCredential(int id) const; + /** + * @brief Gets the credentials containing the provided name. + * @param name The name + * @return The list of credentials matching the name + */ + std::vector getCredentials(const std::string& name) const; + /** + * @brief Adds a credential to the keyring. + * @param credential The Credential to add + * @return True if successful, else false + */ + bool addCredential(const Credential& credential); + /** + * @brief Updates a credential in the keyring. + * @param credential The Credential to update + * @return True if successful, else false + */ + bool updateCredential(const Credential& credential); + /** + * @brief Deletes a credential from the keyring. + * @param id The id of the credential to delete + * @return True if successful, else false + */ + bool deleteCredential(int id); + /** + * @brief Destroys the keyring and all of its data from disk. Once this method is called, the object should no longer be referenced, with or without success. + * @return True if successful, else false + */ + bool destroy(); - private: - /** - * @brief Constructs a Keyring. - * @param store The Store database for the Keyring - */ - Keyring(const Store& store); - Store m_store; + private: + /** + * @brief Constructs a Keyring. + * @param store The Store database for the Keyring + */ + Keyring(const Store& store); + Store m_store; - public: - /** - * @brief Accesses a Keyring. The Keyring will first attempt to load an existing Store. If the Store doesn't exist, it will create a new Store. - * @param name The name of the store - * @param password The password to use for the store. If empty, the password will be fetched/created from the system's credential store - * @return The newly accessed keyring, std::nullopt if accessing failed - */ - static std::optional access(const std::string& name, std::string password = ""); - /** - * @brief Gets whether or not a keyring exists with the provided name. - * @param name The name of the keyring to check - * @return True if a keyring with the provided name exists, else false - */ - static bool exists(const std::string& name); - /** - * @brief Destroys a keyring and all of its data from disk. - * @param The name of the keyring to destroy - * @return True if successful, else false - */ - static bool destroy(const std::string& name); - }; + public: + /** + * @brief Accesses a Keyring. The Keyring will first attempt to load an existing Store. If the Store doesn't exist, it will create a new Store. + * @param name The name of the store + * @param password The password to use for the store. If empty, the password will be fetched/created from the system's credential store + * @return The newly accessed keyring, std::nullopt if accessing failed + */ + static std::optional access(const std::string& name, std::string password = ""); + /** + * @brief Gets whether or not a keyring exists with the provided name. + * @param name The name of the keyring to check + * @return True if a keyring with the provided name exists, else false + */ + static bool exists(const std::string& name); + /** + * @brief Destroys a keyring and all of its data from disk. + * @param The name of the keyring to destroy + * @return True if successful, else false + */ + static bool destroy(const std::string& name); + }; } #endif //KEYRING_H \ No newline at end of file diff --git a/include/keyring/keyringdialogcontroller.h b/include/keyring/keyringdialogcontroller.h index 7453444..fcb53d7 100644 --- a/include/keyring/keyringdialogcontroller.h +++ b/include/keyring/keyringdialogcontroller.h @@ -10,83 +10,83 @@ namespace Nickvision::Keyring { - /** - * @brief A controller for a KeyringDialog. - */ - class KeyringDialogController - { - public: - /** - * @brief Constructs a KeyringDialogController. - * @param name The name of the controller - * @param keyring The keyring managed by the controller, if available - */ - KeyringDialogController(const std::string& name, const std::optional& keyring); - /** - * @brief Gets the keyring managed by the controller, if available. - * @return The keyring if available, else std::nullopt - */ - const std::optional& getKeyring(); - /** - * @brief Gets whether or not the keyring is enabled (unlocked). - * @return True if enabled, else false - */ - bool isEnabled() const; - /** - * @brief Gets whether or not the keyring state is valid. - * @return True if valid, else false - */ - bool isValid() const; - /** - * @brief Enables the keyring. - * @param password The password of the keyring - * @return True if successful, else false - */ - bool enableKeyring(const std::string& password = ""); - /** - * @brief Disables the keyring and destroys its data. - * @return True if successful, else false - */ - bool disableKeyring(); - /** - * @brief Resets the keyring and destroys its data. To be used only if the keyring is locked. If unlocked, use disableKeyring() . - * @return True if successful, else false - */ - bool resetKeyring(); - /** - * @brief Validates a Credential object. - * @param credential The credential to validate - * @return CredentialCheckStatus - */ - CredentialCheckStatus validateCredential(const Credential& credential) const; - /** - * @brief Gets all credentials in the keyring. - * @return The list of all credentials - */ - std::vector getAllCredentials() const; - /** - * @brief Adds a credential to the keyring. - * @param credential The Credential to add - * @return True if successful, else false - */ - bool addCredential(const Credential& credential); - /** - * @brief Updates a credential in the keyring. - * @param credential The Credential to update - * @return True if successful, else false - */ - bool updateCredential(const Credential& credential); - /** - * @brief Deletes a credential from the keyring. - * @param id The id of the credential to delete - * @return True if successful, else false - */ - bool deleteCredential(int id); + /** + * @brief A controller for a KeyringDialog. + */ + class KeyringDialogController + { + public: + /** + * @brief Constructs a KeyringDialogController. + * @param name The name of the controller + * @param keyring The keyring managed by the controller, if available + */ + KeyringDialogController(const std::string& name, const std::optional& keyring); + /** + * @brief Gets the keyring managed by the controller, if available. + * @return The keyring if available, else std::nullopt + */ + const std::optional& getKeyring(); + /** + * @brief Gets whether or not the keyring is enabled (unlocked). + * @return True if enabled, else false + */ + bool isEnabled() const; + /** + * @brief Gets whether or not the keyring state is valid. + * @return True if valid, else false + */ + bool isValid() const; + /** + * @brief Enables the keyring. + * @param password The password of the keyring + * @return True if successful, else false + */ + bool enableKeyring(const std::string& password = ""); + /** + * @brief Disables the keyring and destroys its data. + * @return True if successful, else false + */ + bool disableKeyring(); + /** + * @brief Resets the keyring and destroys its data. To be used only if the keyring is locked. If unlocked, use disableKeyring() . + * @return True if successful, else false + */ + bool resetKeyring(); + /** + * @brief Validates a Credential object. + * @param credential The credential to validate + * @return CredentialCheckStatus + */ + CredentialCheckStatus validateCredential(const Credential& credential) const; + /** + * @brief Gets all credentials in the keyring. + * @return The list of all credentials + */ + std::vector getAllCredentials() const; + /** + * @brief Adds a credential to the keyring. + * @param credential The Credential to add + * @return True if successful, else false + */ + bool addCredential(const Credential& credential); + /** + * @brief Updates a credential in the keyring. + * @param credential The Credential to update + * @return True if successful, else false + */ + bool updateCredential(const Credential& credential); + /** + * @brief Deletes a credential from the keyring. + * @param id The id of the credential to delete + * @return True if successful, else false + */ + bool deleteCredential(int id); - private: - std::string m_name; - std::optional m_keyring; - }; + private: + std::string m_name; + std::optional m_keyring; + }; } #endif //KEYRINGDIALOGCONTROLLER_H \ No newline at end of file diff --git a/include/keyring/passwordcontent.h b/include/keyring/passwordcontent.h index 4d24b7b..3679150 100644 --- a/include/keyring/passwordcontent.h +++ b/include/keyring/passwordcontent.h @@ -5,18 +5,18 @@ namespace Nickvision::Keyring { - /** - * @brief Flags to describe the content of a password. - */ - enum class PasswordContent - { - Numeric = 1, - Uppercase = 2, - Lowercase = 4, - Special = 8 - }; + /** + * @brief Flags to describe the content of a password. + */ + enum class PasswordContent + { + Numeric = 1, + Uppercase = 2, + Lowercase = 4, + Special = 8 + }; - DEFINE_ENUM_FLAG_OPERATORS(PasswordContent); + DEFINE_ENUM_FLAG_OPERATORS(PasswordContent); } #endif //PASSWORDCONTENT_H \ No newline at end of file diff --git a/include/keyring/passwordgenerator.h b/include/keyring/passwordgenerator.h index 291f18c..59a691f 100644 --- a/include/keyring/passwordgenerator.h +++ b/include/keyring/passwordgenerator.h @@ -7,44 +7,44 @@ namespace Nickvision::Keyring { - /** - * @brief A random password generator. - */ - class PasswordGenerator - { - public: - /** - * @brief Constructs a PasswordGenerator. - * @param contentFlags Flags of possible characters in a generated password - */ - PasswordGenerator(PasswordContent contentFlags = PasswordContent::Numeric | PasswordContent::Uppercase | PasswordContent::Lowercase | PasswordContent::Special); - /** - * @brief Gets the flags of possible characters in a generated password. - * @return The flags of possible characters in a generated password - */ - PasswordContent getContentFlags() const; - /** - * @brief Sets the flags of possible characters in a generated password. - * @param contentFlags Flags of possible characters in a generated password - */ - void setContentFlags(PasswordContent contentFlags); - /** - * @brief Generates a new password - * @param length The length of the generated password - * @return The generated password - */ - std::string next(size_t length = 16); + /** + * @brief A random password generator. + */ + class PasswordGenerator + { + public: + /** + * @brief Constructs a PasswordGenerator. + * @param contentFlags Flags of possible characters in a generated password + */ + PasswordGenerator(PasswordContent contentFlags = PasswordContent::Numeric | PasswordContent::Uppercase | PasswordContent::Lowercase | PasswordContent::Special); + /** + * @brief Gets the flags of possible characters in a generated password. + * @return The flags of possible characters in a generated password + */ + PasswordContent getContentFlags() const; + /** + * @brief Sets the flags of possible characters in a generated password. + * @param contentFlags Flags of possible characters in a generated password + */ + void setContentFlags(PasswordContent contentFlags); + /** + * @brief Generates a new password + * @param length The length of the generated password + * @return The generated password + */ + std::string next(size_t length = 16); - private: - std::vector m_chars; - PasswordContent m_contentFlags; + private: + std::vector m_chars; + PasswordContent m_contentFlags; - private: - static std::vector m_numericChars; - static std::vector m_upperChars; - static std::vector m_lowerChars; - static std::vector m_specialChars; - }; + private: + static std::vector m_numericChars; + static std::vector m_upperChars; + static std::vector m_lowerChars; + static std::vector m_specialChars; + }; } #endif //PASSWORDGENERATOR_H \ No newline at end of file diff --git a/include/keyring/store.h b/include/keyring/store.h index 0e8bae7..2bc829e 100644 --- a/include/keyring/store.h +++ b/include/keyring/store.h @@ -16,113 +16,113 @@ namespace Nickvision::Keyring { - /** - * @brief A store object for credentials. Backed by sqlcipher. - */ - class Store - { - public: - /** - * @brief Constructs a Store object. - * @param name The name of the store - * @param password The password of the store - * @throw std::runtime_error Thrown if the store is unable to be created - */ - Store(const std::string& name, const std::string& password); - /** - * @brief Copies a Store object. - * @param store The object to move - */ - Store(const Store& store); - /** - * @brief Moves a Store object. - * @param store The object to move - */ - Store(Store&& store) noexcept; - /** - * @brief Gets the name of the store. - * @return The name of the store - */ - const std::string& getName() const; - /** - * @brief Gets the file path of the store on disk. - * @return The file path of the store - */ - const std::filesystem::path& getPath() const; - /** - * @brief Gets all credentials in the store. - * @return The list of all credentials - */ - std::vector getAllCredentials() const; - /** - * @brief Gets the credential matching the provided id. - * @param id The id of the credential - * @return The credential matching the id, std::nullopt if no matching credential - */ - std::optional getCredential(int id) const; - /** - * @brief Gets the credentials containing the provided name. - * @param name The name - * @return The list of credentials matching the name - */ - std::vector getCredentials(const std::string& name) const; - /** - * @brief Adds a credential to the store. - * @param credential The Credential to add - * @return True if successful, else false - */ - bool addCredential(const Credential& credential); - /** - * @brief Updates a credential in the store. - * @param credential The Credential to update - * @return True if successful, else false - */ - bool updateCredential(const Credential& credential); - /** - * @brief Deletes a credential from the store. - * @param id The id of the credential to delete - * @return True if successful, else false - */ - bool deleteCredential(int id); - /** - * @brief Destroys the store and all of its data from disk. Once this method is called, the object should no longer be referenced, with or without success. - * @return True if successful, else false - */ - bool destroy(); - /** - * @brief Copies a Store object. - * @param store The Store to copy - * @return this - */ - Store& operator=(const Store& store); - /** - * @brief Moves a Store object. - * @param store The Store to move - * @return this - */ - Store& operator=(Store&& store) noexcept; + /** + * @brief A store object for credentials. Backed by sqlcipher. + */ + class Store + { + public: + /** + * @brief Constructs a Store object. + * @param name The name of the store + * @param password The password of the store + * @throw std::runtime_error Thrown if the store is unable to be created + */ + Store(const std::string& name, const std::string& password); + /** + * @brief Copies a Store object. + * @param store The object to move + */ + Store(const Store& store); + /** + * @brief Moves a Store object. + * @param store The object to move + */ + Store(Store&& store) noexcept; + /** + * @brief Gets the name of the store. + * @return The name of the store + */ + const std::string& getName() const; + /** + * @brief Gets the file path of the store on disk. + * @return The file path of the store + */ + const std::filesystem::path& getPath() const; + /** + * @brief Gets all credentials in the store. + * @return The list of all credentials + */ + std::vector getAllCredentials() const; + /** + * @brief Gets the credential matching the provided id. + * @param id The id of the credential + * @return The credential matching the id, std::nullopt if no matching credential + */ + std::optional getCredential(int id) const; + /** + * @brief Gets the credentials containing the provided name. + * @param name The name + * @return The list of credentials matching the name + */ + std::vector getCredentials(const std::string& name) const; + /** + * @brief Adds a credential to the store. + * @param credential The Credential to add + * @return True if successful, else false + */ + bool addCredential(const Credential& credential); + /** + * @brief Updates a credential in the store. + * @param credential The Credential to update + * @return True if successful, else false + */ + bool updateCredential(const Credential& credential); + /** + * @brief Deletes a credential from the store. + * @param id The id of the credential to delete + * @return True if successful, else false + */ + bool deleteCredential(int id); + /** + * @brief Destroys the store and all of its data from disk. Once this method is called, the object should no longer be referenced, with or without success. + * @return True if successful, else false + */ + bool destroy(); + /** + * @brief Copies a Store object. + * @param store The Store to copy + * @return this + */ + Store& operator=(const Store& store); + /** + * @brief Moves a Store object. + * @param store The Store to move + * @return this + */ + Store& operator=(Store&& store) noexcept; - private: - mutable std::mutex m_mutex; - std::string m_name; - std::string m_password; - std::shared_ptr m_database; - std::filesystem::path m_path; + private: + mutable std::mutex m_mutex; + std::string m_name; + std::string m_password; + std::shared_ptr m_database; + std::filesystem::path m_path; - public: - /** - * @brief Gets whether or not a store exists with the provided name. - * @param name The name of the store to check - * @return True if a store with the provided name exists, else false - */ - static bool exists(const std::string& name); - /** - * @brief Destroys a store and all of its data from disk. - * @param The name of the store to destroy - * @return True if successful, else false - */ - static bool destroy(const std::string& name); - }; + public: + /** + * @brief Gets whether or not a store exists with the provided name. + * @param name The name of the store to check + * @return True if a store with the provided name exists, else false + */ + static bool exists(const std::string& name); + /** + * @brief Destroys a store and all of its data from disk. + * @param The name of the store to destroy + * @return True if successful, else false + */ + static bool destroy(const std::string& name); + }; } #endif //STORE_H \ No newline at end of file diff --git a/include/keyring/systemcredentials.h b/include/keyring/systemcredentials.h index 6763e62..00bc159 100644 --- a/include/keyring/systemcredentials.h +++ b/include/keyring/systemcredentials.h @@ -7,36 +7,36 @@ namespace Nickvision::Keyring::SystemCredentials { - /** - * @brief Gets a credential from the system's credential manager. - * @param name The name of the credential - * @return The Credential object, if found - */ - std::optional getCredential(const std::string& name); - /** - * @brief Adds a new credential with a random password to the system's credential manager. - * @param name The name of the credential - * @return The new Credential object, if successful - */ - std::optional addCredential(const std::string& name); - /** - * @brief Adds a new credential to the system's credential manager. On Linux, only the name and password of a credential will be stored. On Windows, all fields of a credential will be stored. - * @param name The new credential object - * @return True if successful, else false - */ - bool addCredential(const Credential& credential); - /** - * @brief Updates a credential in the system's credential manager. On Linux, only the name and password of a credential will be stored. On Windows, all fields of a credential will be stored. - * @param name The updated credential object - * @return True if successful, else false - */ - bool updateCredential(const Credential& credential); - /** - * @brief Deletes a credential from the system's credential manager. - * @param name The name of the credential to delete - * @return True if successful, else false - */ - bool deleteCredential(const std::string& name); + /** + * @brief Gets a credential from the system's credential manager. + * @param name The name of the credential + * @return The Credential object, if found + */ + std::optional getCredential(const std::string& name); + /** + * @brief Adds a new credential with a random password to the system's credential manager. + * @param name The name of the credential + * @return The new Credential object, if successful + */ + std::optional addCredential(const std::string& name); + /** + * @brief Adds a new credential to the system's credential manager. On Linux, only the name and password of a credential will be stored. On Windows, all fields of a credential will be stored. + * @param name The new credential object + * @return True if successful, else false + */ + bool addCredential(const Credential& credential); + /** + * @brief Updates a credential in the system's credential manager. On Linux, only the name and password of a credential will be stored. On Windows, all fields of a credential will be stored. + * @param name The updated credential object + * @return True if successful, else false + */ + bool updateCredential(const Credential& credential); + /** + * @brief Deletes a credential from the system's credential manager. + * @param name The name of the credential to delete + * @return True if successful, else false + */ + bool deleteCredential(const std::string& name); } #endif //SYSTEMCREDENTIALS_H \ No newline at end of file diff --git a/include/localization/documentation.h b/include/localization/documentation.h index 81ff07b..1866f32 100644 --- a/include/localization/documentation.h +++ b/include/localization/documentation.h @@ -5,14 +5,14 @@ namespace Nickvision::Localization::Documentation { - /** - * @brief Gets the url for a documentation page. - * @brief This will be a yelp url for Linux and a website url for Windows and Linux snaps. - * @brief HtmlDocsStore should be set for Aura::getActive()::getAppInfo() - * @param pageName The name of the page to get the url for - * @return The url for the documentation page - */ - std::string getHelpUrl(const std::string& pageName); + /** + * @brief Gets the url for a documentation page. + * @brief This will be a yelp url for Linux and a website url for Windows and Linux snaps. + * @brief HtmlDocsStore should be set for Aura::getActive()::getAppInfo() + * @param pageName The name of the page to get the url for + * @return The url for the documentation page + */ + std::string getHelpUrl(const std::string& pageName); } #endif //DOCUMENTATION \ No newline at end of file diff --git a/include/localization/gettext.h b/include/localization/gettext.h index 4bbfb1c..8a99e48 100644 --- a/include/localization/gettext.h +++ b/include/localization/gettext.h @@ -12,33 +12,33 @@ namespace Nickvision::Localization::Gettext { - /** - * @brief Initializes the gettext system. This function should only be called once, regradless of with different domain names. - * @param domainName The domain name to use for gettext translations - * @return True if initialized, else false - */ - bool init(const std::string& domainName); - /** - * @brief Gets the domain name used for gettext translations. - * @return The gettext domain name - */ - const std::string& getDomainName(); - /** - * @brief Translates a message for a given context. - * @param context The context of the message - * @param msg The message to translate - * @return The translated message for the given context. - */ - const char* pgettext(const char* context, const char* msg); - /** - * @brief Translates a plural message for a given context. - * @param context The context of the message - * @param msg The message to translate - * @param msgPlural The plural version of the message to translate - * @param n The number of objects (used to determine whether or not to use the plural version of the message) - * @return The translated message for the given context and number of objects. - */ - const char* pngettext(const char* context, const char* msg, const char* msgPlural, unsigned long n); + /** + * @brief Initializes the gettext system. This function should only be called once, regradless of with different domain names. + * @param domainName The domain name to use for gettext translations + * @return True if initialized, else false + */ + bool init(const std::string& domainName); + /** + * @brief Gets the domain name used for gettext translations. + * @return The gettext domain name + */ + const std::string& getDomainName(); + /** + * @brief Translates a message for a given context. + * @param context The context of the message + * @param msg The message to translate + * @return The translated message for the given context. + */ + const char* pgettext(const char* context, const char* msg); + /** + * @brief Translates a plural message for a given context. + * @param context The context of the message + * @param msg The message to translate + * @param msgPlural The plural version of the message to translate + * @param n The number of objects (used to determine whether or not to use the plural version of the message) + * @return The translated message for the given context and number of objects. + */ + const char* pngettext(const char* context, const char* msg, const char* msgPlural, unsigned long n); } #endif //GETTEXT_H \ No newline at end of file diff --git a/include/network/networkmonitor.h b/include/network/networkmonitor.h index b3f4af6..9c32698 100644 --- a/include/network/networkmonitor.h +++ b/include/network/networkmonitor.h @@ -12,55 +12,52 @@ namespace Nickvision::Network { - /** - * @brief An object to monitor the state of the system's network connection. - */ - class NetworkMonitor - { - public: - /** - * @brief Constructs a NetworkMonitor. This method will call checkConnectionState() to get the initial system network state. - * @throw std::runtime_error Thrown if unable to create the NetworkMonitor - */ - NetworkMonitor(); - /** - * @brief Destructs a NetworkMonitor. - */ - ~NetworkMonitor(); - /** - * @brief Gets the StateChanged event. This event is invoked whenever the state of the network connection changes. - * @return The StateChanged event - */ - Events::Event& stateChanged(); - /** - * @brief Gets the state of the network connection. - * @return NetworkState - */ - NetworkState getConnectionState() const; + /** + * @brief An object to monitor the state of the system's network connection. + */ + class NetworkMonitor + { + public: + /** + * @brief Constructs a NetworkMonitor. This method will call checkConnectionState() to get the initial system network state. + * @throw std::runtime_error Thrown if unable to create the NetworkMonitor + */ + NetworkMonitor(); + /** + * @brief Destructs a NetworkMonitor. + */ + ~NetworkMonitor(); + /** + * @brief Gets the StateChanged event. This event is invoked whenever the state of the network connection changes. + * @return The StateChanged event + */ + Events::Event& stateChanged(); + /** + * @brief Gets the state of the network connection. + * @return NetworkState + */ + NetworkState getConnectionState() const; - private: - /** - * @brief Manually checks the state of the system's network connection. If a change is detected, the StateChanged event will be invoked. - */ - void checkConnectionState(); - mutable std::mutex m_mutex; - Events::Event m_stateChanged; - NetworkState m_connectionState; + private: + /** + * @brief Manually checks the state of the system's network connection. If a change is detected, the StateChanged event will be invoked. + */ + void checkConnectionState(); + mutable std::mutex m_mutex; + Events::Event m_stateChanged; + NetworkState m_connectionState; #ifdef _WIN32 - void* m_netListManagerEvents; - CComPtr m_netListManager; - CComPtr m_connectionPointContainer; - CComPtr m_connectionPoint; - CComPtr m_sink; - DWORD m_cookie; + void* m_netListManagerEvents; + CComPtr m_netListManager; + CComPtr m_connectionPointContainer; + CComPtr m_connectionPoint; + CComPtr m_sink; + DWORD m_cookie; + friend class NetworkListManagerEvents; #elif defined(__linux__) - unsigned long m_networkChangedHandlerId; + unsigned long m_networkChangedHandlerId; #endif - -#ifdef _WIN32 - friend class NetworkListManagerEvents; -#endif - }; + }; } #endif //NETWORKMONITOR_H \ No newline at end of file diff --git a/include/network/networkstate.h b/include/network/networkstate.h index b236b31..acfd7ce 100644 --- a/include/network/networkstate.h +++ b/include/network/networkstate.h @@ -3,15 +3,15 @@ namespace Nickvision::Network { - /** - * @brief States of a network connection. - */ - enum class NetworkState - { - Disconnected = 0, - ConnectedLocal, - ConnectedGlobal - }; + /** + * @brief States of a network connection. + */ + enum class NetworkState + { + Disconnected = 0, + ConnectedLocal, + ConnectedGlobal + }; } #endif //NETWORKSTATE_H \ No newline at end of file diff --git a/include/network/networkstatechangedeventargs.h b/include/network/networkstatechangedeventargs.h index 6f83858..1d769b7 100644 --- a/include/network/networkstatechangedeventargs.h +++ b/include/network/networkstatechangedeventargs.h @@ -6,26 +6,26 @@ namespace Nickvision::Network { - /** - * @brief Event args for when the network state is changed - */ - class NetworkStateChangedEventArgs : public Events::EventArgs - { - public: - /** - * @brief Constructs a NetworkStateChangedEventArgs. - * @param state NetworkStae - */ - NetworkStateChangedEventArgs(NetworkState state); - /** - * @brief Gets the network state. - * @return NetworkState - */ - NetworkState getState() const; + /** + * @brief Event args for when the network state is changed + */ + class NetworkStateChangedEventArgs : public Events::EventArgs + { + public: + /** + * @brief Constructs a NetworkStateChangedEventArgs. + * @param state NetworkStae + */ + NetworkStateChangedEventArgs(NetworkState state); + /** + * @brief Gets the network state. + * @return NetworkState + */ + NetworkState getState() const; - private: - NetworkState m_state; - }; + private: + NetworkState m_state; + }; } #endif //NETWORKSTATECHANGEDEVENTARGS_H \ No newline at end of file diff --git a/include/notifications/notificationsenteventargs.h b/include/notifications/notificationsenteventargs.h index 418a322..c7de7e1 100644 --- a/include/notifications/notificationsenteventargs.h +++ b/include/notifications/notificationsenteventargs.h @@ -7,47 +7,47 @@ namespace Nickvision::Notifications { - /** - * @brief Event args for when a notification is sent. - */ - class NotificationSentEventArgs : public Events::EventArgs - { - public: - /** - * @brief Constructs a NotificationSentEventArgs. - * @param message The message of the notification - * @param severity The severity of the notification - * @param action An additional action for the notification - * @param actionParam The parameter of the additional action - */ - NotificationSentEventArgs(const std::string& message, NotificationSeverity severity, const std::string& action = "", const std::string& actionParam = ""); - /** - * @brief Gets the message of the notification. - * @return The message of the notification - */ - const std::string& getMessage() const; - /** - * @brief Gets the severity of the notification. - * @return The severity of the notification - */ - NotificationSeverity getSeverity() const; - /** - * @brief Gets the optional action of the notification. - * @return The optional action of the notification - */ - const std::string& getAction() const; - /** - * @brief Gets the parameter of the optional action. - * @return The parameter of the optional action - */ - const std::string& getActionParam() const; + /** + * @brief Event args for when a notification is sent. + */ + class NotificationSentEventArgs : public Events::EventArgs + { + public: + /** + * @brief Constructs a NotificationSentEventArgs. + * @param message The message of the notification + * @param severity The severity of the notification + * @param action An additional action for the notification + * @param actionParam The parameter of the additional action + */ + NotificationSentEventArgs(const std::string& message, NotificationSeverity severity, const std::string& action = "", const std::string& actionParam = ""); + /** + * @brief Gets the message of the notification. + * @return The message of the notification + */ + const std::string& getMessage() const; + /** + * @brief Gets the severity of the notification. + * @return The severity of the notification + */ + NotificationSeverity getSeverity() const; + /** + * @brief Gets the optional action of the notification. + * @return The optional action of the notification + */ + const std::string& getAction() const; + /** + * @brief Gets the parameter of the optional action. + * @return The parameter of the optional action + */ + const std::string& getActionParam() const; - protected: - std::string m_message; - NotificationSeverity m_severity; - std::string m_action; - std::string m_actionParam; - }; + protected: + std::string m_message; + NotificationSeverity m_severity; + std::string m_action; + std::string m_actionParam; + }; } #endif //NOTIFICATIONSENTEVENTARGS_H \ No newline at end of file diff --git a/include/notifications/notificationseverity.h b/include/notifications/notificationseverity.h index 4d7b240..32794e6 100644 --- a/include/notifications/notificationseverity.h +++ b/include/notifications/notificationseverity.h @@ -3,16 +3,16 @@ namespace Nickvision::Notifications { - /** - * @brief Severities for a notification. - */ - enum class NotificationSeverity - { - Informational = 0, - Success, - Warning, - Error - }; + /** + * @brief Severities for a notification. + */ + enum class NotificationSeverity + { + Informational = 0, + Success, + Warning, + Error + }; } #endif //NOTIFICATIONSEVERITY_H \ No newline at end of file diff --git a/include/notifications/notifyicon.h b/include/notifications/notifyicon.h index e527ae1..dceb20e 100644 --- a/include/notifications/notifyicon.h +++ b/include/notifications/notifyicon.h @@ -15,87 +15,87 @@ namespace Nickvision::Notifications { - /** - * @brief An icon for the system tray. - * @brief This API is only available on Windows. - */ - class NotifyIcon - { - public: - /** - * @brief Constructs a NotifyIcon. - * @param hwnd The HWND handle of the main application window - * @param menu The model for the context menu of the NotifyIcon - * @param hidden Whether or not the NotifyIcon should be hidden by default - * @throw std::runtime_error Thrown if unable to create the NotifyIcon - */ - NotifyIcon(HWND hwnd, const NotifyIconMenu& contextMenu = { }, bool hidden = false); - /** - * @brief Destructs a NotifyIcon. - */ - ~NotifyIcon(); - /** - * @brief Hides the icon. - * @return True if icon was hidden, else false - */ - bool hide(); - /** - * @brief Shows the icon. - * @return True if icon was shown, else false - */ - bool show(); - /** - * @brief Gets the tooltip text of the icon. - * @return The tooltip text - */ - const std::string& getTooltip() const; - /** - * @brief Sets the tooltip text of the icon. - * @param tooltip The toolip text - * @return True if the tooltip was updated, else false - */ - bool setTooltip(const std::string& tooltip); - /** - * @brief Shows a notification from the icon. - * @brief Supports the action "open" with action param being a path of a file or folder to open. - * @param e ShellNotificationSentEventArgs - * @return True if notification was shown from the icon - */ - bool notify(const ShellNotificationSentEventArgs& e); + /** + * @brief An icon for the system tray. + * @brief This API is only available on Windows. + */ + class NotifyIcon + { + public: + /** + * @brief Constructs a NotifyIcon. + * @param hwnd The HWND handle of the main application window + * @param menu The model for the context menu of the NotifyIcon + * @param hidden Whether or not the NotifyIcon should be hidden by default + * @throw std::runtime_error Thrown if unable to create the NotifyIcon + */ + NotifyIcon(HWND hwnd, const NotifyIconMenu& contextMenu = { }, bool hidden = false); + /** + * @brief Destructs a NotifyIcon. + */ + ~NotifyIcon(); + /** + * @brief Hides the icon. + * @return True if icon was hidden, else false + */ + bool hide(); + /** + * @brief Shows the icon. + * @return True if icon was shown, else false + */ + bool show(); + /** + * @brief Gets the tooltip text of the icon. + * @return The tooltip text + */ + const std::string& getTooltip() const; + /** + * @brief Sets the tooltip text of the icon. + * @param tooltip The toolip text + * @return True if the tooltip was updated, else false + */ + bool setTooltip(const std::string& tooltip); + /** + * @brief Shows a notification from the icon. + * @brief Supports the action "open" with action param being a path of a file or folder to open. + * @param e ShellNotificationSentEventArgs + * @return True if notification was shown from the icon + */ + bool notify(const ShellNotificationSentEventArgs& e); - private: - /** - * @brief Gets a basic NOTIFYICONDATAA struct for this NotifyIcon. - * @return NOTIFYICONDATAA - */ - NOTIFYICONDATAA getBaseNotifyIconData(); - /** - * @brief Handles a WM_NOTIFYICON_EVENT message. - * @param wParam WPARAM - * @param lParam LPARAM - * @return LRESULT - */ - LRESULT handleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam); - std::string m_className; - bool m_isHidden; - std::string m_tooltip; - NotifyIconMenu m_contextMenu; - HWND m_hwnd; - GUID m_guid; - HMENU m_hmenu; - std::filesystem::path m_openPath; + private: + /** + * @brief Gets a basic NOTIFYICONDATAA struct for this NotifyIcon. + * @return NOTIFYICONDATAA + */ + NOTIFYICONDATAA getBaseNotifyIconData(); + /** + * @brief Handles a WM_NOTIFYICON_EVENT message. + * @param wParam WPARAM + * @param lParam LPARAM + * @return LRESULT + */ + LRESULT handleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam); + std::string m_className; + bool m_isHidden; + std::string m_tooltip; + NotifyIconMenu m_contextMenu; + HWND m_hwnd; + GUID m_guid; + HMENU m_hmenu; + std::filesystem::path m_openPath; - private: - static std::map m_icons; - /** - * @brief The window procedure for NotifyIcons - * @param hwnd HWND - * @param uMsg UINT - * @param wParam WPARAM - * @param lParam LPARAM - */ - static LRESULT notifyIconWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); - }; + private: + static std::map m_icons; + /** + * @brief The window procedure for NotifyIcons + * @param hwnd HWND + * @param uMsg UINT + * @param wParam WPARAM + * @param lParam LPARAM + */ + static LRESULT notifyIconWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); + }; } #endif //NOTIFYICON_H diff --git a/include/notifications/notifyiconmenu.h b/include/notifications/notifyiconmenu.h index 820b2bc..166f33e 100644 --- a/include/notifications/notifyiconmenu.h +++ b/include/notifications/notifyiconmenu.h @@ -9,150 +9,150 @@ namespace Nickvision::Notifications { - /** - * @brief Types of menu items for a NotifyIcon. - */ - enum class NotifyIconMenuItemType - { - Action = 0, - Separator = 1 - }; + /** + * @brief Types of menu items for a NotifyIcon. + */ + enum class NotifyIconMenuItemType + { + Action = 0, + Separator = 1 + }; - /** - * @brief A generic menu item for a NotifyIcon. - */ - class NotifyIconMenuItem - { - public: - /** - * @brief Constructs a NotifyIconMenuItem. - * @param type The type of menu item - */ - NotifyIconMenuItem(NotifyIconMenuItemType type); - /** - * @brief Destructs a NotifyIconMenuItem. - */ - virtual ~NotifyIconMenuItem() = default; - /** - * @brief Gets the type of the menu item. - * @return NotifyIconMenuItemType - */ - NotifyIconMenuItemType getType() const; + /** + * @brief A generic menu item for a NotifyIcon. + */ + class NotifyIconMenuItem + { + public: + /** + * @brief Constructs a NotifyIconMenuItem. + * @param type The type of menu item + */ + NotifyIconMenuItem(NotifyIconMenuItemType type); + /** + * @brief Destructs a NotifyIconMenuItem. + */ + virtual ~NotifyIconMenuItem() = default; + /** + * @brief Gets the type of the menu item. + * @return NotifyIconMenuItemType + */ + NotifyIconMenuItemType getType() const; - private: - NotifyIconMenuItemType m_type; - }; + private: + NotifyIconMenuItemType m_type; + }; - /** - * @brief A separator menu item for a NotifyIcon. - */ - class NotifyIconSeparatorMenuItem : public NotifyIconMenuItem - { - public: - /** - * @brief Constructs a NotifyIconSeparatorMenuItem. - */ - NotifyIconSeparatorMenuItem(); - }; + /** + * @brief A separator menu item for a NotifyIcon. + */ + class NotifyIconSeparatorMenuItem : public NotifyIconMenuItem + { + public: + /** + * @brief Constructs a NotifyIconSeparatorMenuItem. + */ + NotifyIconSeparatorMenuItem(); + }; - /** - * @brief An actionable menu item for a NotifyIcon. - */ - class NotifyIconActionMenuItem : public NotifyIconMenuItem - { - public: - /** - * @brief Constructs a NotifyIconActionMenuItem. - * @param label The label for the menu item - * @param action The function to call when the menu item is clicked - */ - NotifyIconActionMenuItem(const std::string& label, const std::function& action); - /** - * @brief Gets the label for the menu item. - * @return The label for the menu item - */ - const std::string& getLabel() const; - /** - * @brief Calls the callback function of the menu item. - */ - void invoke() const; - /** - * @brief Calls the callback function of the menu item. - */ - void operator()() const; + /** + * @brief An actionable menu item for a NotifyIcon. + */ + class NotifyIconActionMenuItem : public NotifyIconMenuItem + { + public: + /** + * @brief Constructs a NotifyIconActionMenuItem. + * @param label The label for the menu item + * @param action The function to call when the menu item is clicked + */ + NotifyIconActionMenuItem(const std::string& label, const std::function& action); + /** + * @brief Gets the label for the menu item. + * @return The label for the menu item + */ + const std::string& getLabel() const; + /** + * @brief Calls the callback function of the menu item. + */ + void invoke() const; + /** + * @brief Calls the callback function of the menu item. + */ + void operator()() const; - private: - std::string m_label; - std::function m_action; - }; + private: + std::string m_label; + std::function m_action; + }; - /** - * @brief A menu for a NotifyIcon. - */ - class NotifyIconMenu - { - public: - /** - * @brief Constructs a NotifyIconMenu. - */ - NotifyIconMenu() = default; - /** - * @brief Gets the number of items in the menu. - * @return The number of items in the menu - */ - size_t size() const; - /** - * @brief Gets whether or not the menu is empty. - * @return True if the menu is empty, else false - */ - bool empty() const; - /** - * @brief Gets the NotifyIconMenuItem at a given index in the menu. - * @returns The NotifyIconMenuItem at the given index. nullptr if the index is invalid; - */ - const std::shared_ptr& get(size_t index) const; - /** - * @brief Adds a separator to the bottom of the menu. - * @return The index at which the separator was added - */ - size_t addSeparator(); - /** - * @brief Inserts a separator at a given index in the menu. - * @param index The index at which to insert the separator - * @return True if the separator was successfully inserted, else false - */ - bool insertSeparator(size_t index); - /** - * @brief Removes a separator at a given index in the menu. - * @param index The index at which to remove the separator - * @return True if the separator was successfully removed, else false - */ - bool removeSeparator(size_t index); - /** - * @brief Adds an action item to the bottom of the menu. - * @param label The label of the action - * @param action The callback function of the action - * @return The index at which the action item was added - */ - size_t addAction(const std::string& label, const std::function& action); - /** - * @brief Inserts an action item at a given index in the menu. - * @param index The index at which to insert the action item - * @param label The label of the action - * @param action The callback function of the action - * @return True if the action item was successfully inserted, else false - */ - bool insertAction(size_t index, const std::string& label, const std::function& action); - /** - * @brief Removes an action item at a given index in the menu. - * @param index The index at which to remove the action item - * @return True if the action item was successfully removed, else false - */ - bool removeAction(size_t index); + /** + * @brief A menu for a NotifyIcon. + */ + class NotifyIconMenu + { + public: + /** + * @brief Constructs a NotifyIconMenu. + */ + NotifyIconMenu() = default; + /** + * @brief Gets the number of items in the menu. + * @return The number of items in the menu + */ + size_t size() const; + /** + * @brief Gets whether or not the menu is empty. + * @return True if the menu is empty, else false + */ + bool empty() const; + /** + * @brief Gets the NotifyIconMenuItem at a given index in the menu. + * @returns The NotifyIconMenuItem at the given index. nullptr if the index is invalid; + */ + const std::shared_ptr& get(size_t index) const; + /** + * @brief Adds a separator to the bottom of the menu. + * @return The index at which the separator was added + */ + size_t addSeparator(); + /** + * @brief Inserts a separator at a given index in the menu. + * @param index The index at which to insert the separator + * @return True if the separator was successfully inserted, else false + */ + bool insertSeparator(size_t index); + /** + * @brief Removes a separator at a given index in the menu. + * @param index The index at which to remove the separator + * @return True if the separator was successfully removed, else false + */ + bool removeSeparator(size_t index); + /** + * @brief Adds an action item to the bottom of the menu. + * @param label The label of the action + * @param action The callback function of the action + * @return The index at which the action item was added + */ + size_t addAction(const std::string& label, const std::function& action); + /** + * @brief Inserts an action item at a given index in the menu. + * @param index The index at which to insert the action item + * @param label The label of the action + * @param action The callback function of the action + * @return True if the action item was successfully inserted, else false + */ + bool insertAction(size_t index, const std::string& label, const std::function& action); + /** + * @brief Removes an action item at a given index in the menu. + * @param index The index at which to remove the action item + * @return True if the action item was successfully removed, else false + */ + bool removeAction(size_t index); - private: - std::vector> m_items; - }; + private: + std::vector> m_items; + }; } #endif //NOTIFYICONMENU_H diff --git a/include/notifications/shellnotification.h b/include/notifications/shellnotification.h index 7c99193..c02a15f 100644 --- a/include/notifications/shellnotification.h +++ b/include/notifications/shellnotification.h @@ -10,23 +10,23 @@ namespace Nickvision::Notifications::ShellNotification { #ifdef _WIN32 - /** - * @brief Sends a notification to the desktop. - * @brief Uses Nickvision::Notifications::NotifyIcon. - * @brief Supports the action "open" with action param being a path of a file or folder to open. - * @param e ShellNotificationSentEventArgs - * @param hwnd The HWND handle of the main application window. This parameter is only used once on the initial creation of the static NotifyIcon and then is ignored on future calls - */ - void send(const ShellNotificationSentEventArgs& e, HWND hwnd); + /** + * @brief Sends a notification to the desktop. + * @brief Uses Nickvision::Notifications::NotifyIcon. + * @brief Supports the action "open" with action param being a path of a file or folder to open. + * @param e ShellNotificationSentEventArgs + * @param hwnd The HWND handle of the main application window. This parameter is only used once on the initial creation of the static NotifyIcon and then is ignored on future calls + */ + void send(const ShellNotificationSentEventArgs& e, HWND hwnd); #elif defined(__linux__) - /** - * @brief Sends a notification to the shell. - * @brief Uses Gio.Notification on Linux. - * @brief Supports the action "open" with action param being a path of a file or folder to open. The app must define an "app.open" action to handle this event. - * @param e ShellNotificationSentEventArgs - * @param openText Localized text of "Open" - */ - void send(const ShellNotificationSentEventArgs& e, const std::string& openText); + /** + * @brief Sends a notification to the shell. + * @brief Uses Gio.Notification on Linux. + * @brief Supports the action "open" with action param being a path of a file or folder to open. The app must define an "app.open" action to handle this event. + * @param e ShellNotificationSentEventArgs + * @param openText Localized text of "Open" + */ + void send(const ShellNotificationSentEventArgs& e, const std::string& openText); #endif } diff --git a/include/notifications/shellnotificationsenteventargs.h b/include/notifications/shellnotificationsenteventargs.h index b921c6a..db91419 100644 --- a/include/notifications/shellnotificationsenteventargs.h +++ b/include/notifications/shellnotificationsenteventargs.h @@ -5,30 +5,30 @@ namespace Nickvision::Notifications { - /** - * @brief Event args for when a shell notification is sent. - */ - class ShellNotificationSentEventArgs : public NotificationSentEventArgs - { - public: - /** - * @brief Constructs a ShellNotificationSentEventArgs. - * @param title The title of the notification - * @param message The message of the notification - * @param severity The severity of the notification - * @param action An additional action for the notification - * @param actionParam The parameter of the additional action - */ - ShellNotificationSentEventArgs(const std::string& title, const std::string& message, NotificationSeverity severity, const std::string& action = "", const std::string& actionParam = ""); - /** - * @brief Gets the title of the notification. - * @return The title of the notification - */ - const std::string& getTitle() const; + /** + * @brief Event args for when a shell notification is sent. + */ + class ShellNotificationSentEventArgs : public NotificationSentEventArgs + { + public: + /** + * @brief Constructs a ShellNotificationSentEventArgs. + * @param title The title of the notification + * @param message The message of the notification + * @param severity The severity of the notification + * @param action An additional action for the notification + * @param actionParam The parameter of the additional action + */ + ShellNotificationSentEventArgs(const std::string& title, const std::string& message, NotificationSeverity severity, const std::string& action = "", const std::string& actionParam = ""); + /** + * @brief Gets the title of the notification. + * @return The title of the notification + */ + const std::string& getTitle() const; - protected: - std::string m_title; - }; + protected: + std::string m_title; + }; } #endif //SHELLNOTIFICATIONSENTEVENTARGS_H \ No newline at end of file diff --git a/include/taskbar/progressstate.h b/include/taskbar/progressstate.h index 9209fb4..1e2ecf1 100644 --- a/include/taskbar/progressstate.h +++ b/include/taskbar/progressstate.h @@ -3,17 +3,17 @@ namespace Nickvision::Taskbar { - /** - * @brief States of progress on a taskbar button. - */ - enum class ProgressState - { - NoProgress = 0, - Indeterminate = 1, - Normal = 2, - Error = 4, - Paused = 8 - }; + /** + * @brief States of progress on a taskbar button. + */ + enum class ProgressState + { + NoProgress = 0, + Indeterminate = 1, + Normal = 2, + Error = 4, + Paused = 8 + }; } #endif //PROGRESSSTATE_H \ No newline at end of file diff --git a/include/taskbar/taskbaritem.h b/include/taskbar/taskbaritem.h index aee1f62..c5d69e2 100644 --- a/include/taskbar/taskbaritem.h +++ b/include/taskbar/taskbaritem.h @@ -16,108 +16,108 @@ namespace Nickvision::Taskbar { - /** - * @brief An item on the taskbar. - */ - class TaskbarItem - { - public: - /** - * @brief Constructs a TaskbarItem. - */ - TaskbarItem(); - /** - * @brief Destructs a TaskbarItem. - */ - ~TaskbarItem(); - /** - * @brieg Gets the state of the progress. - * @return ProgressState - */ - ProgressState getProgressState() const; - /** - * @brief Sets the state of the progress. - * @param state The new ProgressState - */ - void setProgressState(ProgressState state); - /** - * @brief Gets the value of the progress. - * @return The progress value - */ - double getProgress() const; - /** - * @brief Sets the value of the progress. Setting the progress value will set the progress state to Normal if progress > 0, else will set progress state to NoProgress. - * @brief Should be a value between 0 and 1. - * @param progress The new progress value - */ - void setProgress(double progress); - /** - * @brief Gets whether or not the taskbar item is shown in an urgent state. - * @return True if in urgent state, else false - */ - bool getUrgent() const; - /** - * @brief Sets whether or not the taskbar item is shown in an urgent state. - * @param urgent True for urgent state, else false - */ - void setUrgent(bool urgent); - /** - * @brief Gets whether or not the count is visible on the taskbar item. - * @return True if count visible, else false - */ - bool getCountVisible() const; - /** - * @brief Sets whether or not the count is visible on the taskbar item. - * @param countVisible True for visible count, else false - */ - void setCountVisible(bool countVisible); - /** - * @brief Gets the count shown on the taskbar item. - * @return The count value - */ - long getCount() const; - /** - * @brief Sets the count shown on the taskbar item. Setting the count will set the count visible to true if count > 0, else will set count visible to false. - * @param count The new count value - */ - void setCount(long count); + /** + * @brief An item on the taskbar. + */ + class TaskbarItem + { + public: + /** + * @brief Constructs a TaskbarItem. + */ + TaskbarItem(); + /** + * @brief Destructs a TaskbarItem. + */ + ~TaskbarItem(); + /** + * @brieg Gets the state of the progress. + * @return ProgressState + */ + ProgressState getProgressState() const; + /** + * @brief Sets the state of the progress. + * @param state The new ProgressState + */ + void setProgressState(ProgressState state); + /** + * @brief Gets the value of the progress. + * @return The progress value + */ + double getProgress() const; + /** + * @brief Sets the value of the progress. Setting the progress value will set the progress state to Normal if progress > 0, else will set progress state to NoProgress. + * @brief Should be a value between 0 and 1. + * @param progress The new progress value + */ + void setProgress(double progress); + /** + * @brief Gets whether or not the taskbar item is shown in an urgent state. + * @return True if in urgent state, else false + */ + bool getUrgent() const; + /** + * @brief Sets whether or not the taskbar item is shown in an urgent state. + * @param urgent True for urgent state, else false + */ + void setUrgent(bool urgent); + /** + * @brief Gets whether or not the count is visible on the taskbar item. + * @return True if count visible, else false + */ + bool getCountVisible() const; + /** + * @brief Sets whether or not the count is visible on the taskbar item. + * @param countVisible True for visible count, else false + */ + void setCountVisible(bool countVisible); + /** + * @brief Gets the count shown on the taskbar item. + * @return The count value + */ + long getCount() const; + /** + * @brief Sets the count shown on the taskbar item. Setting the count will set the count visible to true if count > 0, else will set count visible to false. + * @param count The new count value + */ + void setCount(long count); #ifdef _WIN32 - /** - * @brief Connects a taskbar item to the application. - * @param hwnd The HWND of the main application window - * @return True if connection successful, else false - */ - bool connect(HWND hwnd); + /** + * @brief Connects a taskbar item to the application. + * @param hwnd The HWND of the main application window + * @return True if connection successful, else false + */ + bool connect(HWND hwnd); #elif defined(__linux__) - /** - * @brief Connects a taskbar item to the application. - * @param desktopFile The desktop file name with the file extension of the running application - * @return True if connection successful, else false - */ - bool connect(const std::string& desktopFile); + /** + * @brief Connects a taskbar item to the application. + * @param desktopFile The desktop file name with the file extension of the running application + * @return True if connection successful, else false + */ + bool connect(const std::string& desktopFile); #endif - private: - mutable std::mutex m_mutex; - ProgressState m_progressState; - double m_progress; - bool m_urgent; - bool m_countVisible; - long m_count; + private: + mutable std::mutex m_mutex; + ProgressState m_progressState; + double m_progress; + bool m_urgent; + bool m_countVisible; + long m_count; #ifdef _WIN32 - HWND m_hwnd; - CComPtr m_taskbar; - ULONG_PTR m_gdi; + HWND m_hwnd; + CComPtr m_taskbar; + ULONG_PTR m_gdi; #elif defined(__linux__) - /** - * @brief Sends the com.canonical.Unity.LauncherEntry.Update signal over the session dbus. - */ - void sendDBusUpdate(); - GDBusConnection* m_connection; - std::string m_objectPath; - std::string m_appUri; + /** + * @brief Sends the com.canonical.Unity.LauncherEntry.Update signal over the session dbus. + */ + void sendDBusUpdate(); + GDBusConnection* m_connection; + std::string m_objectPath; + std::string m_appUri; #endif - }; + }; } #endif //TASKBARITEM_H \ No newline at end of file diff --git a/include/update/version.h b/include/update/version.h index 614695e..102242c 100644 --- a/include/update/version.h +++ b/include/update/version.h @@ -7,121 +7,121 @@ namespace Nickvision::Update { - /** - * @brief A model for a version number. Formatted in "major.minor.build-dev". - */ - class Version - { - public: - /** - * @brief Constructs a Version. - */ - Version(); - /** - * @brief Constructs a Version. - * @param major The major number - * @param minor The minor number - * @param build The build number - */ - Version(int major, int minor, int build); - /** - * @brief Constructs a Version. - * @param major The major number - * @param minor The minor number - * @param build The build number - * @param dev The dev string - * @throw std::invalid_argument Thrown when the dev version does not contain a "-" - */ - Version(int major, int minor, int build, const std::string& dev); - /** - * @brief Constructs a Version. - * @param version A version string to parse - * @throw std::invalid_argument Thrown when the version string is not formatted correctly - */ - Version(const std::string& version); - /** - * @brief Gets the major number of the version. - * @return The major number - */ - int getMajor() const; - /** - * @brief Gets the minor number of the version. - * @return The minor number - */ - int getMinor() const; - /** - * @brief Gets the build number of the version. - * @return The build number - */ - int getBuild() const; - /** - * @brief Gets the dev string of the version. - * @return The dev string - */ - const std::string& getDev() const; - /** - * @brief Gets the type of the version. - * @return VersionType - */ - VersionType getVersionType() const; - /** - * @brief Gets a string representation of the Version. - * @return The string representation of the Version - */ - const std::string& toString() const; - /** - * @brief Gets whether or not the Version object is empty - * @return True if empty, else false - */ - bool empty() const; - /** - * @brief Compares Version objects via < operator - * @param compare The Version object to compare too - * @return True if this < compare - */ - bool operator<(const Version& compare) const; - /** - * @brief Compares Version objects via <= operator - * @param compare The Version object to compare too - * @return True if this <= compare - */ - bool operator<=(const Version& compare) const; - /** - * @brief Compares Version objects via > operator - * @param compare The Version object to compare too - * @return True if this > compare - */ - bool operator>(const Version& compare) const; - /** - * @brief Compares Version objects via >= operator - * @param compare The Version object to compare too - * @return True if this >= compare - */ - bool operator>=(const Version& compare) const; - /** - * @brief Compares Version objects via == operator - * @param compare The Version object to compare too - * @return True if this == compare - */ - bool operator==(const Version& compare) const; - /** - * @brief Compares Version objects via != operator - * @param compare The Version object to compare too - * @return True if this != compare - */ - bool operator!=(const Version& compare) const; - /** - * @brief Outputs the Version object - */ - friend std::ostream& operator<<(std::ostream& os, const Version& version); + /** + * @brief A model for a version number. Formatted in "major.minor.build-dev". + */ + class Version + { + public: + /** + * @brief Constructs a Version. + */ + Version(); + /** + * @brief Constructs a Version. + * @param major The major number + * @param minor The minor number + * @param build The build number + */ + Version(int major, int minor, int build); + /** + * @brief Constructs a Version. + * @param major The major number + * @param minor The minor number + * @param build The build number + * @param dev The dev string + * @throw std::invalid_argument Thrown when the dev version does not contain a "-" + */ + Version(int major, int minor, int build, const std::string& dev); + /** + * @brief Constructs a Version. + * @param version A version string to parse + * @throw std::invalid_argument Thrown when the version string is not formatted correctly + */ + Version(const std::string& version); + /** + * @brief Gets the major number of the version. + * @return The major number + */ + int getMajor() const; + /** + * @brief Gets the minor number of the version. + * @return The minor number + */ + int getMinor() const; + /** + * @brief Gets the build number of the version. + * @return The build number + */ + int getBuild() const; + /** + * @brief Gets the dev string of the version. + * @return The dev string + */ + const std::string& getDev() const; + /** + * @brief Gets the type of the version. + * @return VersionType + */ + VersionType getVersionType() const; + /** + * @brief Gets a string representation of the Version. + * @return The string representation of the Version + */ + const std::string& toString() const; + /** + * @brief Gets whether or not the Version object is empty + * @return True if empty, else false + */ + bool empty() const; + /** + * @brief Compares Version objects via < operator + * @param compare The Version object to compare too + * @return True if this < compare + */ + bool operator<(const Version& compare) const; + /** + * @brief Compares Version objects via <= operator + * @param compare The Version object to compare too + * @return True if this <= compare + */ + bool operator<=(const Version& compare) const; + /** + * @brief Compares Version objects via > operator + * @param compare The Version object to compare too + * @return True if this > compare + */ + bool operator>(const Version& compare) const; + /** + * @brief Compares Version objects via >= operator + * @param compare The Version object to compare too + * @return True if this >= compare + */ + bool operator>=(const Version& compare) const; + /** + * @brief Compares Version objects via == operator + * @param compare The Version object to compare too + * @return True if this == compare + */ + bool operator==(const Version& compare) const; + /** + * @brief Compares Version objects via != operator + * @param compare The Version object to compare too + * @return True if this != compare + */ + bool operator!=(const Version& compare) const; + /** + * @brief Outputs the Version object + */ + friend std::ostream& operator<<(std::ostream& os, const Version& version); - private: - int m_major; - int m_minor; - int m_build; - std::string m_dev; - std::string m_str; - }; + private: + int m_major; + int m_minor; + int m_build; + std::string m_dev; + std::string m_str; + }; } #endif // VERSION_H \ No newline at end of file diff --git a/include/update/versiontype.h b/include/update/versiontype.h index f6d0884..a5668d6 100644 --- a/include/update/versiontype.h +++ b/include/update/versiontype.h @@ -3,14 +3,14 @@ namespace Nickvision::Update { - /** - * @brief Types of a version. - */ - enum class VersionType - { - Stable = 0, - Preview - }; + /** + * @brief Types of a version. + */ + enum class VersionType + { + Stable = 0, + Preview + }; } #endif //VERSIONTYPE_H \ No newline at end of file From 4e7c89996c575e124a632d209abc5807913de3ce Mon Sep 17 00:00:00 2001 From: Nick Logozzo Date: Mon, 29 Jan 2024 20:18:14 -0500 Subject: [PATCH 05/10] Fix Source File Spacing --- include/taskbar/taskbaritem.h | 4 + src/app/appinfo.cpp | 464 ++++++++-------- src/app/configurationbase.cpp | 58 +- src/filesystem/filesystemchangedeventargs.cpp | 26 +- src/filesystem/filesystemwatcher.cpp | 436 +++++++-------- src/filesystem/systemdirectories.cpp | 26 +- src/filesystem/userdirectories.cpp | 422 +++++++------- src/helpers/webhelpers.cpp | 188 +++---- src/keyring/credential.cpp | 188 +++---- src/keyring/keyring.cpp | 168 +++--- src/keyring/keyringdialogcontroller.cpp | 200 +++---- src/keyring/passwordgenerator.cpp | 76 +-- src/keyring/passwordstrength.cpp | 88 +-- src/keyring/store.cpp | 516 +++++++++--------- src/keyring/systemcredentials.cpp | 234 ++++---- src/localization/documentation.cpp | 10 +- src/localization/gettext.cpp | 80 +-- src/network/networkmonitor.cpp | 278 +++++----- src/network/networkstatechangedeventargs.cpp | 16 +- .../notificationsenteventargs.cpp | 46 +- src/notifications/notifyicon.cpp | 492 ++++++++--------- src/notifications/notifyiconmenu.cpp | 248 ++++----- src/notifications/shellnotification.cpp | 104 ++-- .../shellnotificationsenteventargs.cpp | 18 +- src/update/version.cpp | 382 ++++++------- 25 files changed, 2386 insertions(+), 2382 deletions(-) diff --git a/include/taskbar/taskbaritem.h b/include/taskbar/taskbaritem.h index c5d69e2..d96eea3 100644 --- a/include/taskbar/taskbaritem.h +++ b/include/taskbar/taskbaritem.h @@ -105,6 +105,10 @@ namespace Nickvision::Taskbar bool m_countVisible; long m_count; #ifdef _WIN32 + /** + * @brief Draws the icon with the item's count on the TaskbarItem. + */ + void drawCountIcon(); HWND m_hwnd; CComPtr m_taskbar; ULONG_PTR m_gdi; diff --git a/src/app/appinfo.cpp b/src/app/appinfo.cpp index 9705884..8b8b96f 100644 --- a/src/app/appinfo.cpp +++ b/src/app/appinfo.cpp @@ -7,236 +7,236 @@ using namespace Nickvision::Update; namespace Nickvision::App { - const std::string& AppInfo::getId() const - { - return m_id; - } - - void AppInfo::setId(const std::string& id) - { - m_id = id; - } - - const std::string& AppInfo::getName() const - { - return m_name; - } - - void AppInfo::setName(const std::string& name) - { - m_name = name; - } - - const std::string& AppInfo::getShortName() const - { - return m_shortName; - } - - void AppInfo::setShortName(const std::string& shortName) - { - m_shortName = shortName; - } - - const std::string& AppInfo::getEnglishShortName() const - { - return m_englishShortName; - } - - void AppInfo::setEnglishShortName(const std::string& englishShortName) - { - m_englishShortName = englishShortName; - } - - const std::string& AppInfo::getDescription() const - { - return m_description; - } - - void AppInfo::setDescription(const std::string& description) - { - m_description = description; - } - - const Version& AppInfo::getVersion() const - { - return m_version; - } - - void AppInfo::setVersion(const Version& version) - { - m_version = version; - } - - const std::string& AppInfo::getChangelog() const - { - return m_changelog; - } - - void AppInfo::setChangelog(const std::string& changelog) - { - m_changelog = changelog; - if (m_changelog.empty()) - { - m_htmlChangelog = ""; - return; - } - std::stringstream markdown; - for(const std::string& line : StringHelpers::split(StringHelpers::trim(m_changelog), "\n")) - { - if (line.empty()) - { - continue; - } - markdown << StringHelpers::trim(line); - markdown << std::endl; - } - maddy::Parser parser; - m_htmlChangelog = parser.Parse(markdown); - } - - const std::string& AppInfo::getHtmlChangelog() const - { - return m_htmlChangelog; - } - - const std::string& AppInfo::getSourceRepo() const - { - return m_sourceRepo; - } - - bool AppInfo::setSourceRepo(const std::string& sourceRepo) - { - if (!StringHelpers::isValidUrl(sourceRepo)) - { - return false; - } - m_sourceRepo = sourceRepo; - return true; - } - - const std::string& AppInfo::getIssueTracker() const - { - return m_issueTracker; - } - - bool AppInfo::setIssueTracker(const std::string& issueTracker) - { - if (!StringHelpers::isValidUrl(issueTracker)) - { - return false; - } - m_issueTracker = issueTracker; - return true; - } - - const std::string& AppInfo::getSupportUrl() const - { - return m_supportUrl; - } - - bool AppInfo::setSupportUrl(const std::string& supportUrl) - { - if (!StringHelpers::isValidUrl(supportUrl)) - { - return false; - } - m_supportUrl = supportUrl; - return true; - } - - const std::string& AppInfo::getHtmlDocsStore() const - { - return m_htmlDocsStore; - } - - void AppInfo::setHtmlDocsStore(const std::string& htmlDocsStore) - { - m_htmlDocsStore = htmlDocsStore; - } - - std::map& AppInfo::getExtraLinks() - { - return m_extraLinks; - } - - const std::map& AppInfo::getExtraLinks() const - { - return m_extraLinks; - } - - std::map& AppInfo::getDevelopers() - { - return m_developers; - } - - const std::map& AppInfo::getDevelopers() const - { - return m_developers; - } - - std::map& AppInfo::getDesigners() - { - return m_designers; - } - - const std::map& AppInfo::getDesigners() const - { - return m_designers; - } - - std::map& AppInfo::getArtists() - { - return m_artists; - } - - const std::map& AppInfo::getArtists() const - { - return m_artists; - } - - const std::string& AppInfo::getTranslatorCredits() const - { - return m_translatorCredits; - } - - void AppInfo::setTranslatorCredits(const std::string& translatorCredits) - { - m_translatorCredits = translatorCredits; - } - - std::vector AppInfo::getTranslatorNames() const - { - if (m_translatorCredits.empty()) - { - return { }; - } - std::vector vec; - for (const std::string& line : StringHelpers::split(m_translatorCredits, "\n")) - { - size_t index; - if ((index = line.find('<')) != std::string::npos) - { - vec.push_back(StringHelpers::trim(line.substr(0, index))); - } - else if ((index = line.find("http")) != std::string::npos) - { - vec.push_back(StringHelpers::trim(line.substr(0, index))); - } - else - { - vec.push_back(line); - } - } - return vec; - } - - std::vector AppInfo::convertUrlMapToVector(const std::map& urls) - { - std::vector vec; - for (const std::pair& pair : urls) - { - vec.push_back(pair.first + " " + pair.second); - } - return vec; - } + const std::string& AppInfo::getId() const + { + return m_id; + } + + void AppInfo::setId(const std::string& id) + { + m_id = id; + } + + const std::string& AppInfo::getName() const + { + return m_name; + } + + void AppInfo::setName(const std::string& name) + { + m_name = name; + } + + const std::string& AppInfo::getShortName() const + { + return m_shortName; + } + + void AppInfo::setShortName(const std::string& shortName) + { + m_shortName = shortName; + } + + const std::string& AppInfo::getEnglishShortName() const + { + return m_englishShortName; + } + + void AppInfo::setEnglishShortName(const std::string& englishShortName) + { + m_englishShortName = englishShortName; + } + + const std::string& AppInfo::getDescription() const + { + return m_description; + } + + void AppInfo::setDescription(const std::string& description) + { + m_description = description; + } + + const Version& AppInfo::getVersion() const + { + return m_version; + } + + void AppInfo::setVersion(const Version& version) + { + m_version = version; + } + + const std::string& AppInfo::getChangelog() const + { + return m_changelog; + } + + void AppInfo::setChangelog(const std::string& changelog) + { + m_changelog = changelog; + if (m_changelog.empty()) + { + m_htmlChangelog = ""; + return; + } + std::stringstream markdown; + for(const std::string& line : StringHelpers::split(StringHelpers::trim(m_changelog), "\n")) + { + if (line.empty()) + { + continue; + } + markdown << StringHelpers::trim(line); + markdown << std::endl; + } + maddy::Parser parser; + m_htmlChangelog = parser.Parse(markdown); + } + + const std::string& AppInfo::getHtmlChangelog() const + { + return m_htmlChangelog; + } + + const std::string& AppInfo::getSourceRepo() const + { + return m_sourceRepo; + } + + bool AppInfo::setSourceRepo(const std::string& sourceRepo) + { + if (!StringHelpers::isValidUrl(sourceRepo)) + { + return false; + } + m_sourceRepo = sourceRepo; + return true; + } + + const std::string& AppInfo::getIssueTracker() const + { + return m_issueTracker; + } + + bool AppInfo::setIssueTracker(const std::string& issueTracker) + { + if (!StringHelpers::isValidUrl(issueTracker)) + { + return false; + } + m_issueTracker = issueTracker; + return true; + } + + const std::string& AppInfo::getSupportUrl() const + { + return m_supportUrl; + } + + bool AppInfo::setSupportUrl(const std::string& supportUrl) + { + if (!StringHelpers::isValidUrl(supportUrl)) + { + return false; + } + m_supportUrl = supportUrl; + return true; + } + + const std::string& AppInfo::getHtmlDocsStore() const + { + return m_htmlDocsStore; + } + + void AppInfo::setHtmlDocsStore(const std::string& htmlDocsStore) + { + m_htmlDocsStore = htmlDocsStore; + } + + std::map& AppInfo::getExtraLinks() + { + return m_extraLinks; + } + + const std::map& AppInfo::getExtraLinks() const + { + return m_extraLinks; + } + + std::map& AppInfo::getDevelopers() + { + return m_developers; + } + + const std::map& AppInfo::getDevelopers() const + { + return m_developers; + } + + std::map& AppInfo::getDesigners() + { + return m_designers; + } + + const std::map& AppInfo::getDesigners() const + { + return m_designers; + } + + std::map& AppInfo::getArtists() + { + return m_artists; + } + + const std::map& AppInfo::getArtists() const + { + return m_artists; + } + + const std::string& AppInfo::getTranslatorCredits() const + { + return m_translatorCredits; + } + + void AppInfo::setTranslatorCredits(const std::string& translatorCredits) + { + m_translatorCredits = translatorCredits; + } + + std::vector AppInfo::getTranslatorNames() const + { + if (m_translatorCredits.empty()) + { + return { }; + } + std::vector vec; + for (const std::string& line : StringHelpers::split(m_translatorCredits, "\n")) + { + size_t index; + if ((index = line.find('<')) != std::string::npos) + { + vec.push_back(StringHelpers::trim(line.substr(0, index))); + } + else if ((index = line.find("http")) != std::string::npos) + { + vec.push_back(StringHelpers::trim(line.substr(0, index))); + } + else + { + vec.push_back(line); + } + } + return vec; + } + + std::vector AppInfo::convertUrlMapToVector(const std::map& urls) + { + std::vector vec; + for (const std::pair& pair : urls) + { + vec.push_back(pair.first + " " + pair.second); + } + return vec; + } } \ No newline at end of file diff --git a/src/app/configurationbase.cpp b/src/app/configurationbase.cpp index fcb1dc0..f1787e6 100644 --- a/src/app/configurationbase.cpp +++ b/src/app/configurationbase.cpp @@ -7,36 +7,36 @@ using namespace Nickvision::Filesystem; namespace Nickvision::App { - ConfigurationBase::ConfigurationBase(const std::string& key) - : m_key{ key } - { - if (m_key.empty()) - { - throw std::invalid_argument("Key must not be empty."); - } - m_path = UserDirectories::getApplicationConfig() / (key + ".json"); - if (std::filesystem::exists(m_path)) - { - std::ifstream in{ m_path }; - in >> m_json; - } - } + ConfigurationBase::ConfigurationBase(const std::string& key) + : m_key{ key } + { + if (m_key.empty()) + { + throw std::invalid_argument("Key must not be empty."); + } + m_path = UserDirectories::getApplicationConfig() / (key + ".json"); + if (std::filesystem::exists(m_path)) + { + std::ifstream in{ m_path }; + in >> m_json; + } + } - const std::string& ConfigurationBase::getKey() const - { - return m_key; - } + const std::string& ConfigurationBase::getKey() const + { + return m_key; + } - Events::Event& ConfigurationBase::saved() - { - return m_saved; - } + Events::Event& ConfigurationBase::saved() + { + return m_saved; + } - bool ConfigurationBase::save() - { - std::ofstream out{ m_path }; - out << m_json; - m_saved({}); - return true; - } + bool ConfigurationBase::save() + { + std::ofstream out{ m_path }; + out << m_json; + m_saved({}); + return true; + } } \ No newline at end of file diff --git a/src/filesystem/filesystemchangedeventargs.cpp b/src/filesystem/filesystemchangedeventargs.cpp index b10e0f4..557f8a6 100644 --- a/src/filesystem/filesystemchangedeventargs.cpp +++ b/src/filesystem/filesystemchangedeventargs.cpp @@ -2,20 +2,20 @@ namespace Nickvision::Filesystem { - FileSystemChangedEventArgs::FileSystemChangedEventArgs(const std::filesystem::path& path, FileAction why) - : m_path{ path }, - m_why{ why } - { + FileSystemChangedEventArgs::FileSystemChangedEventArgs(const std::filesystem::path& path, FileAction why) + : m_path{ path }, + m_why{ why } + { - } + } - const std::filesystem::path& FileSystemChangedEventArgs::getPath() const - { - return m_path; - } + const std::filesystem::path& FileSystemChangedEventArgs::getPath() const + { + return m_path; + } - FileAction FileSystemChangedEventArgs::getWhy() const - { - return m_why; - } + FileAction FileSystemChangedEventArgs::getWhy() const + { + return m_why; + } } \ No newline at end of file diff --git a/src/filesystem/filesystemwatcher.cpp b/src/filesystem/filesystemwatcher.cpp index b393ebe..18f822a 100644 --- a/src/filesystem/filesystemwatcher.cpp +++ b/src/filesystem/filesystemwatcher.cpp @@ -9,241 +9,241 @@ namespace Nickvision::Filesystem { - FileSystemWatcher::FileSystemWatcher(const std::filesystem::path& path, bool incudeSubdirectories, WatcherFlags watcherFlags) - : m_path{ path }, - m_includeSubdirectories{ incudeSubdirectories }, - m_watcherFlags{ watcherFlags }, - m_watching{ true } - { + FileSystemWatcher::FileSystemWatcher(const std::filesystem::path& path, bool incudeSubdirectories, WatcherFlags watcherFlags) + : m_path{ path }, + m_includeSubdirectories{ incudeSubdirectories }, + m_watcherFlags{ watcherFlags }, + m_watching{ true } + { #ifdef _WIN32 - m_terminateEvent = CreateEventA(nullptr, 1, 0, nullptr); - if (!m_terminateEvent) - { - throw std::runtime_error("Unable to create event."); - } + m_terminateEvent = CreateEventA(nullptr, 1, 0, nullptr); + if (!m_terminateEvent) + { + throw std::runtime_error("Unable to create event."); + } #elif defined(__linux__) - m_notify = inotify_init1(IN_NONBLOCK | IN_CLOEXEC); - if (m_notify == -1) - { - throw std::runtime_error("Unable to init inotify."); - } + m_notify = inotify_init1(IN_NONBLOCK | IN_CLOEXEC); + if (m_notify == -1) + { + throw std::runtime_error("Unable to init inotify."); + } #endif - m_watchThread = std::jthread(&FileSystemWatcher::watch, this); - } + m_watchThread = std::jthread(&FileSystemWatcher::watch, this); + } - FileSystemWatcher::~FileSystemWatcher() - { - m_watching = false; + FileSystemWatcher::~FileSystemWatcher() + { + m_watching = false; #ifdef _WIN32 - SetEvent(m_terminateEvent); - CloseHandle(m_terminateEvent); + SetEvent(m_terminateEvent); + CloseHandle(m_terminateEvent); #elif defined(__linux__) - close(m_notify); + close(m_notify); #endif - } + } - const std::filesystem::path& FileSystemWatcher::getPath() const - { - return m_path; - } + const std::filesystem::path& FileSystemWatcher::getPath() const + { + return m_path; + } - WatcherFlags FileSystemWatcher::getWatcherFlags() const - { - return m_watcherFlags; - } + WatcherFlags FileSystemWatcher::getWatcherFlags() const + { + return m_watcherFlags; + } - bool FileSystemWatcher::getIncludeSubdirectories() const - { - return m_includeSubdirectories; - } + bool FileSystemWatcher::getIncludeSubdirectories() const + { + return m_includeSubdirectories; + } - Events::Event& FileSystemWatcher::changed() - { - return m_changed; - } + Events::Event& FileSystemWatcher::changed() + { + return m_changed; + } - bool FileSystemWatcher::isExtensionWatched(const std::filesystem::path& extension) - { - std::lock_guard lock{ m_mutex }; - if (m_extensionFilters.size() == 0) - { - return true; - } - return std::find(m_extensionFilters.begin(), m_extensionFilters.end(), extension) != m_extensionFilters.end(); - } + bool FileSystemWatcher::isExtensionWatched(const std::filesystem::path& extension) + { + std::lock_guard lock{ m_mutex }; + if (m_extensionFilters.size() == 0) + { + return true; + } + return std::find(m_extensionFilters.begin(), m_extensionFilters.end(), extension) != m_extensionFilters.end(); + } - bool FileSystemWatcher::addExtensionFilter(const std::filesystem::path& extension) - { - std::lock_guard lock{ m_mutex }; - if (std::find(m_extensionFilters.begin(), m_extensionFilters.end(), extension) == m_extensionFilters.end()) - { - m_extensionFilters.push_back(extension); - return true; - } - return false; - } + bool FileSystemWatcher::addExtensionFilter(const std::filesystem::path& extension) + { + std::lock_guard lock{ m_mutex }; + if (std::find(m_extensionFilters.begin(), m_extensionFilters.end(), extension) == m_extensionFilters.end()) + { + m_extensionFilters.push_back(extension); + return true; + } + return false; + } - bool FileSystemWatcher::removeExtensionFilter(const std::filesystem::path& extension) - { - std::lock_guard lock{ m_mutex }; - auto find{ std::find(m_extensionFilters.begin(), m_extensionFilters.end(), extension) }; - if (find != m_extensionFilters.end()) - { - m_extensionFilters.erase(find); - return true; - } - return false; - } + bool FileSystemWatcher::removeExtensionFilter(const std::filesystem::path& extension) + { + std::lock_guard lock{ m_mutex }; + auto find{ std::find(m_extensionFilters.begin(), m_extensionFilters.end(), extension) }; + if (find != m_extensionFilters.end()) + { + m_extensionFilters.erase(find); + return true; + } + return false; + } - bool FileSystemWatcher::clearExtensionFilters() - { - std::lock_guard lock{ m_mutex }; - m_extensionFilters.clear(); - return true; - } + bool FileSystemWatcher::clearExtensionFilters() + { + std::lock_guard lock{ m_mutex }; + m_extensionFilters.clear(); + return true; + } - void FileSystemWatcher::watch() - { + void FileSystemWatcher::watch() + { #ifdef _WIN32 - HANDLE folder{ CreateFileW(m_path.c_str(), FILE_LIST_DIRECTORY, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, nullptr, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED, nullptr) }; - if (folder == INVALID_HANDLE_VALUE) - { - return; - } - OVERLAPPED overlapped{ 0 }; - overlapped.hEvent = CreateEvent(nullptr, 1, 0, nullptr); - if (!overlapped.hEvent) - { - CloseHandle(folder); - return; - } - std::vector buffer(1024 * 256); - DWORD bytes{ 0 }; - bool pending{ false }; - HANDLE events[2]{ overlapped.hEvent, m_terminateEvent }; - while (m_watching) - { - pending = ReadDirectoryChangesW(folder, &buffer[0], DWORD(buffer.size()), m_includeSubdirectories ? 1 : 0, DWORD(m_watcherFlags), &bytes, &overlapped, nullptr); - if (WaitForMultipleObjects(2, events, 0, INFINITE) == WAIT_OBJECT_0) - { - if (!GetOverlappedResult(folder, &overlapped, &bytes, 1) || bytes == 0) - { - CloseHandle(folder); - return; - } - pending = false; - FILE_NOTIFY_INFORMATION* info{ reinterpret_cast(&buffer[0]) }; - while (true) - { - if (info->Action != FILE_ACTION_RENAMED_NEW_NAME) - { - std::filesystem::path changed{ std::wstring(info->FileName, info->FileNameLength / sizeof(info->FileName[0])) }; - if (isExtensionWatched(changed.extension())) - { - m_changed({ changed , static_cast(info->Action) }); - } - } - if (info->NextEntryOffset == 0) - { - break; - } - info = reinterpret_cast(reinterpret_cast(info) + info->NextEntryOffset); - } - } - else - { - break; - } - } - if (pending) - { - CancelIo(folder); - GetOverlappedResult(folder, &overlapped, &bytes, TRUE); - } - CloseHandle(folder); + HANDLE folder{ CreateFileW(m_path.c_str(), FILE_LIST_DIRECTORY, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, nullptr, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED, nullptr) }; + if (folder == INVALID_HANDLE_VALUE) + { + return; + } + OVERLAPPED overlapped{ 0 }; + overlapped.hEvent = CreateEvent(nullptr, 1, 0, nullptr); + if (!overlapped.hEvent) + { + CloseHandle(folder); + return; + } + std::vector buffer(1024 * 256); + DWORD bytes{ 0 }; + bool pending{ false }; + HANDLE events[2]{ overlapped.hEvent, m_terminateEvent }; + while (m_watching) + { + pending = ReadDirectoryChangesW(folder, &buffer[0], DWORD(buffer.size()), m_includeSubdirectories ? 1 : 0, DWORD(m_watcherFlags), &bytes, &overlapped, nullptr); + if (WaitForMultipleObjects(2, events, 0, INFINITE) == WAIT_OBJECT_0) + { + if (!GetOverlappedResult(folder, &overlapped, &bytes, 1) || bytes == 0) + { + CloseHandle(folder); + return; + } + pending = false; + FILE_NOTIFY_INFORMATION* info{ reinterpret_cast(&buffer[0]) }; + while (true) + { + if (info->Action != FILE_ACTION_RENAMED_NEW_NAME) + { + std::filesystem::path changed{ std::wstring(info->FileName, info->FileNameLength / sizeof(info->FileName[0])) }; + if (isExtensionWatched(changed.extension())) + { + m_changed({ changed , static_cast(info->Action) }); + } + } + if (info->NextEntryOffset == 0) + { + break; + } + info = reinterpret_cast(reinterpret_cast(info) + info->NextEntryOffset); + } + } + else + { + break; + } + } + if (pending) + { + CancelIo(folder); + GetOverlappedResult(folder, &overlapped, &bytes, TRUE); + } + CloseHandle(folder); #elif defined(__linux__) - int mask{ 0 }; - if ((m_watcherFlags & WatcherFlags::FileName) == WatcherFlags::FileName) - { - mask |= IN_CREATE; - mask |= IN_DELETE; - mask |= IN_MOVED_FROM; - } - if ((m_watcherFlags & WatcherFlags::DirectoryName) == WatcherFlags::DirectoryName) - { - mask |= IN_DELETE_SELF; - mask |= IN_MOVE_SELF; - } - if ((m_watcherFlags & WatcherFlags::Attributes) == WatcherFlags::Attributes) - { - mask |= IN_ATTRIB; - } - if ((m_watcherFlags & WatcherFlags::Size) == WatcherFlags::Size) - { - mask |= IN_MODIFY; - } - if ((m_watcherFlags & WatcherFlags::LastWrite) == WatcherFlags::LastWrite) - { - mask |= IN_CLOSE_WRITE; - } - if ((m_watcherFlags & WatcherFlags::LastAccess) == WatcherFlags::LastAccess) - { - mask |= IN_ACCESS; - mask |= IN_OPEN; - } - std::vector watches; - watches.push_back(inotify_add_watch(m_notify, m_path.c_str(), mask)); - if (m_includeSubdirectories) - { - for (const std::filesystem::directory_entry& e : std::filesystem::recursive_directory_iterator(m_path)) - { - if (e.is_directory()) - { - watches.push_back(inotify_add_watch(m_notify, e.path().string().c_str(), mask)); - } - } - } - while (m_watching) - { - std::vector buf(1024 * (sizeof(struct inotify_event) + 16)); - ssize_t length{ read(m_notify, &buf[0], buf.size()) }; - if (length < 0) - { - continue; - } - struct inotify_event* event{ nullptr }; - for (ssize_t i = 0; i < length; i += sizeof(struct inotify_event) + event->len) - { - event = reinterpret_cast(&buf[i]); - if (event->len) - { - std::filesystem::path changed{ m_path / event->name }; - if (isExtensionWatched(changed.extension())) - { - if (event->mask & IN_CREATE) - { - m_changed({ changed , FileAction::Added }); - } - else if ((event->mask & IN_DELETE) || (event->mask & IN_DELETE_SELF)) - { - m_changed({ changed , FileAction::Removed }); - } - else if ((event->mask & IN_MOVED_FROM) || (event->mask & IN_MOVE_SELF)) - { - m_changed({ changed , FileAction::Renamed }); - } - else - { - m_changed({ changed , FileAction::Modified }); - } - } - } - } - } - for (int watch : watches) - { - inotify_rm_watch(m_notify, watch); - } + int mask{ 0 }; + if ((m_watcherFlags & WatcherFlags::FileName) == WatcherFlags::FileName) + { + mask |= IN_CREATE; + mask |= IN_DELETE; + mask |= IN_MOVED_FROM; + } + if ((m_watcherFlags & WatcherFlags::DirectoryName) == WatcherFlags::DirectoryName) + { + mask |= IN_DELETE_SELF; + mask |= IN_MOVE_SELF; + } + if ((m_watcherFlags & WatcherFlags::Attributes) == WatcherFlags::Attributes) + { + mask |= IN_ATTRIB; + } + if ((m_watcherFlags & WatcherFlags::Size) == WatcherFlags::Size) + { + mask |= IN_MODIFY; + } + if ((m_watcherFlags & WatcherFlags::LastWrite) == WatcherFlags::LastWrite) + { + mask |= IN_CLOSE_WRITE; + } + if ((m_watcherFlags & WatcherFlags::LastAccess) == WatcherFlags::LastAccess) + { + mask |= IN_ACCESS; + mask |= IN_OPEN; + } + std::vector watches; + watches.push_back(inotify_add_watch(m_notify, m_path.c_str(), mask)); + if (m_includeSubdirectories) + { + for (const std::filesystem::directory_entry& e : std::filesystem::recursive_directory_iterator(m_path)) + { + if (e.is_directory()) + { + watches.push_back(inotify_add_watch(m_notify, e.path().string().c_str(), mask)); + } + } + } + while (m_watching) + { + std::vector buf(1024 * (sizeof(struct inotify_event) + 16)); + ssize_t length{ read(m_notify, &buf[0], buf.size()) }; + if (length < 0) + { + continue; + } + struct inotify_event* event{ nullptr }; + for (ssize_t i = 0; i < length; i += sizeof(struct inotify_event) + event->len) + { + event = reinterpret_cast(&buf[i]); + if (event->len) + { + std::filesystem::path changed{ m_path / event->name }; + if (isExtensionWatched(changed.extension())) + { + if (event->mask & IN_CREATE) + { + m_changed({ changed , FileAction::Added }); + } + else if ((event->mask & IN_DELETE) || (event->mask & IN_DELETE_SELF)) + { + m_changed({ changed , FileAction::Removed }); + } + else if ((event->mask & IN_MOVED_FROM) || (event->mask & IN_MOVE_SELF)) + { + m_changed({ changed , FileAction::Renamed }); + } + else + { + m_changed({ changed , FileAction::Modified }); + } + } + } + } + } + for (int watch : watches) + { + inotify_rm_watch(m_notify, watch); + } #endif - } + } } \ No newline at end of file diff --git a/src/filesystem/systemdirectories.cpp b/src/filesystem/systemdirectories.cpp index 6c7ebb0..43f006e 100644 --- a/src/filesystem/systemdirectories.cpp +++ b/src/filesystem/systemdirectories.cpp @@ -9,29 +9,29 @@ namespace Nickvision::Filesystem static std::vector getFromVar(const std::string& var) { std::string env{ Aura::getActive().getEnvVar(var) }; - if (!env.empty()) - { + if (!env.empty()) + { #ifdef _WIN32 return StringHelpers::split(env, ";"); #elif defined(__linux__) return StringHelpers::split(env, ":"); #endif - } - return {}; + } + return {}; } - std::vector SystemDirectories::getPath() - { + std::vector SystemDirectories::getPath() + { return getFromVar("PATH"); - } + } - std::vector SystemDirectories::getConfig() - { + std::vector SystemDirectories::getConfig() + { return getFromVar("XDG_CONFIG_DIRS"); - } + } - std::vector SystemDirectories::getData() - { + std::vector SystemDirectories::getData() + { return getFromVar("XDG_DATA_DIRS"); - } + } } \ No newline at end of file diff --git a/src/filesystem/userdirectories.cpp b/src/filesystem/userdirectories.cpp index 8e7645e..2cb29b6 100644 --- a/src/filesystem/userdirectories.cpp +++ b/src/filesystem/userdirectories.cpp @@ -17,269 +17,269 @@ using namespace Nickvision::App; namespace Nickvision::Filesystem { #ifdef __linux__ - static std::filesystem::path getXDGDir(const std::string& key) - { - std::string var{ Aura::getActive().getEnvVar(key) }; - if (!var.empty()) - { - return var; - } - std::filesystem::path dirsPath{ UserDirectories::getConfig() / "user-dirs.dirs" }; - if (!std::filesystem::exists(dirsPath)) - { - return {}; - } - std::ifstream dirs{ dirsPath }; - std::string line; - while (std::getline(dirs, line)) - { - if (line[0] == '#' || line.empty()) - { - continue; - } - std::vector pair{ StringHelpers::split(line, "=") }; - if (pair[0] == key) - { - if (pair[1].find("$HOME") != std::string::npos) - { - pair[1].replace(pair[1].find("$HOME"), 5, UserDirectories::getHome().string()); - } - return StringHelpers::trim(pair[1], '"'); - } - } - return { }; - } + static std::filesystem::path getXDGDir(const std::string& key) + { + std::string var{ Aura::getActive().getEnvVar(key) }; + if (!var.empty()) + { + return var; + } + std::filesystem::path dirsPath{ UserDirectories::getConfig() / "user-dirs.dirs" }; + if (!std::filesystem::exists(dirsPath)) + { + return {}; + } + std::ifstream dirs{ dirsPath }; + std::string line; + while (std::getline(dirs, line)) + { + if (line[0] == '#' || line.empty()) + { + continue; + } + std::vector pair{ StringHelpers::split(line, "=") }; + if (pair[0] == key) + { + if (pair[1].find("$HOME") != std::string::npos) + { + pair[1].replace(pair[1].find("$HOME"), 5, UserDirectories::getHome().string()); + } + return StringHelpers::trim(pair[1], '"'); + } + } + return { }; + } #endif - std::filesystem::path UserDirectories::getHome() - { - std::filesystem::path result; + std::filesystem::path UserDirectories::getHome() + { + std::filesystem::path result; #ifdef _WIN32 - wchar_t* p{ nullptr }; - if (SHGetKnownFolderPath(FOLDERID_Profile, 0, nullptr, &p) == S_OK) - { - result = p; - } - CoTaskMemFree(static_cast(p)); + wchar_t* p{ nullptr }; + if (SHGetKnownFolderPath(FOLDERID_Profile, 0, nullptr, &p) == S_OK) + { + result = p; + } + CoTaskMemFree(static_cast(p)); #elif defined(__linux__) - std::filesystem::path var{ Aura::getActive().getEnvVar("HOME") }; - result = !var.empty() ? var : getpwuid(getuid())->pw_dir; + std::filesystem::path var{ Aura::getActive().getEnvVar("HOME") }; + result = !var.empty() ? var : getpwuid(getuid())->pw_dir; #endif - return result; - } + return result; + } - std::filesystem::path UserDirectories::getConfig() - { - std::filesystem::path result; + std::filesystem::path UserDirectories::getConfig() + { + std::filesystem::path result; #ifdef _WIN32 - wchar_t* p{ nullptr }; - if (SHGetKnownFolderPath(FOLDERID_RoamingAppData, 0, nullptr, &p) == S_OK) - { - result = p; - } - CoTaskMemFree(static_cast(p)); + wchar_t* p{ nullptr }; + if (SHGetKnownFolderPath(FOLDERID_RoamingAppData, 0, nullptr, &p) == S_OK) + { + result = p; + } + CoTaskMemFree(static_cast(p)); #elif defined(__linux__) - std::filesystem::path var{ Aura::getActive().getEnvVar("XDG_CONFIG_HOME") }; - result = !var.empty() ? var : (getHome() / ".config"); + std::filesystem::path var{ Aura::getActive().getEnvVar("XDG_CONFIG_HOME") }; + result = !var.empty() ? var : (getHome() / ".config"); #endif - std::filesystem::create_directories(result); - return result; - } + std::filesystem::create_directories(result); + return result; + } - std::filesystem::path UserDirectories::getApplicationConfig() - { - std::filesystem::path result = getConfig() / Aura::getActive().getAppInfo().getName(); - std::filesystem::create_directories(result); - return result; - } + std::filesystem::path UserDirectories::getApplicationConfig() + { + std::filesystem::path result = getConfig() / Aura::getActive().getAppInfo().getName(); + std::filesystem::create_directories(result); + return result; + } - std::filesystem::path UserDirectories::getCache() - { - std::filesystem::path result; + std::filesystem::path UserDirectories::getCache() + { + std::filesystem::path result; #ifdef _WIN32 - wchar_t* p{ nullptr }; - if (SHGetKnownFolderPath(FOLDERID_LocalAppData, 0, nullptr, &p) == S_OK) - { - result = p; - } - CoTaskMemFree(static_cast(p)); + wchar_t* p{ nullptr }; + if (SHGetKnownFolderPath(FOLDERID_LocalAppData, 0, nullptr, &p) == S_OK) + { + result = p; + } + CoTaskMemFree(static_cast(p)); #elif defined(__linux__) - std::filesystem::path var{ Aura::getActive().getEnvVar("XDG_CACHE_HOME") }; - result = !var.empty() ? var : (getHome() / ".cache"); + std::filesystem::path var{ Aura::getActive().getEnvVar("XDG_CACHE_HOME") }; + result = !var.empty() ? var : (getHome() / ".cache"); #endif - std::filesystem::create_directories(result); - return result; - } + std::filesystem::create_directories(result); + return result; + } - std::filesystem::path UserDirectories::getApplicationCache() - { - std::filesystem::path result = getCache() / Aura::getActive().getAppInfo().getName(); - std::filesystem::create_directories(result); - return result; - } + std::filesystem::path UserDirectories::getApplicationCache() + { + std::filesystem::path result = getCache() / Aura::getActive().getAppInfo().getName(); + std::filesystem::create_directories(result); + return result; + } - std::filesystem::path UserDirectories::getLocalData() - { - std::filesystem::path result; + std::filesystem::path UserDirectories::getLocalData() + { + std::filesystem::path result; #ifdef _WIN32 - result = getConfig(); + result = getConfig(); #elif defined(__linux__) - std::filesystem::path var{ Aura::getActive().getEnvVar("XDG_DATA_HOME") }; - result = !var.empty() ? var : (getHome() / ".local/share"); + std::filesystem::path var{ Aura::getActive().getEnvVar("XDG_DATA_HOME") }; + result = !var.empty() ? var : (getHome() / ".local/share"); #endif - std::filesystem::create_directories(result); - return result; - } + std::filesystem::create_directories(result); + return result; + } - std::filesystem::path UserDirectories::getApplicationLocalData() - { - std::filesystem::path result{ getLocalData() / Aura::getActive().getAppInfo().getName() }; - std::filesystem::create_directories(result); - return result; - } + std::filesystem::path UserDirectories::getApplicationLocalData() + { + std::filesystem::path result{ getLocalData() / Aura::getActive().getAppInfo().getName() }; + std::filesystem::create_directories(result); + return result; + } - std::filesystem::path UserDirectories::getRuntime() - { - std::filesystem::path result; + std::filesystem::path UserDirectories::getRuntime() + { + std::filesystem::path result; #ifdef __linux__ - std::filesystem::path var{ Aura::getActive().getEnvVar("XDG_RUNTIME_DIR") }; - result = !var.empty() ? var : (std::filesystem::path("/run/user/") / Aura::getActive().getEnvVar("UID")); + std::filesystem::path var{ Aura::getActive().getEnvVar("XDG_RUNTIME_DIR") }; + result = !var.empty() ? var : (std::filesystem::path("/run/user/") / Aura::getActive().getEnvVar("UID")); #endif - return result; - } + return result; + } - std::filesystem::path UserDirectories::getDesktop() - { - std::filesystem::path result; + std::filesystem::path UserDirectories::getDesktop() + { + std::filesystem::path result; #ifdef _WIN32 - wchar_t* p{ nullptr }; - if (SHGetKnownFolderPath(FOLDERID_Desktop, 0, nullptr, &p) == S_OK) - { - result = p; - } - CoTaskMemFree(static_cast(p)); + wchar_t* p{ nullptr }; + if (SHGetKnownFolderPath(FOLDERID_Desktop, 0, nullptr, &p) == S_OK) + { + result = p; + } + CoTaskMemFree(static_cast(p)); #elif defined(__linux__) - result = getXDGDir("XDG_DESKTOP_DIR"); - result = result.empty() ? (getHome() / "Desktop") : result; + result = getXDGDir("XDG_DESKTOP_DIR"); + result = result.empty() ? (getHome() / "Desktop") : result; #endif - std::filesystem::create_directories(result); - return result; - } + std::filesystem::create_directories(result); + return result; + } - std::filesystem::path UserDirectories::getDocuments() - { - std::filesystem::path result; + std::filesystem::path UserDirectories::getDocuments() + { + std::filesystem::path result; #ifdef _WIN32 - wchar_t* p{ nullptr }; - if (SHGetKnownFolderPath(FOLDERID_Documents, 0, nullptr, &p) == S_OK) - { - result = p; - } - CoTaskMemFree(static_cast(p)); + wchar_t* p{ nullptr }; + if (SHGetKnownFolderPath(FOLDERID_Documents, 0, nullptr, &p) == S_OK) + { + result = p; + } + CoTaskMemFree(static_cast(p)); #elif defined(__linux__) - result = getXDGDir("XDG_DOCUMENTS_DIR"); - result = result.empty() ? (getHome() / "Documents") : result; + result = getXDGDir("XDG_DOCUMENTS_DIR"); + result = result.empty() ? (getHome() / "Documents") : result; #endif - std::filesystem::create_directories(result); - return result; - } + std::filesystem::create_directories(result); + return result; + } - std::filesystem::path UserDirectories::getDownloads() - { - std::filesystem::path result; + std::filesystem::path UserDirectories::getDownloads() + { + std::filesystem::path result; #ifdef _WIN32 - wchar_t* p{ nullptr }; - if (SHGetKnownFolderPath(FOLDERID_Downloads, 0, nullptr, &p) == S_OK) - { - result = p; - } - CoTaskMemFree(static_cast(p)); + wchar_t* p{ nullptr }; + if (SHGetKnownFolderPath(FOLDERID_Downloads, 0, nullptr, &p) == S_OK) + { + result = p; + } + CoTaskMemFree(static_cast(p)); #elif defined(__linux__) - result = getXDGDir("XDG_DOWNLOAD_DIR"); - result = result.empty() ? (getHome() / "Downloads") : result; + result = getXDGDir("XDG_DOWNLOAD_DIR"); + result = result.empty() ? (getHome() / "Downloads") : result; #endif - std::filesystem::create_directories(result); - return result; - } + std::filesystem::create_directories(result); + return result; + } - std::filesystem::path UserDirectories::getMusic() - { - std::filesystem::path result; + std::filesystem::path UserDirectories::getMusic() + { + std::filesystem::path result; #ifdef _WIN32 - wchar_t* p{ nullptr }; - if (SHGetKnownFolderPath(FOLDERID_Music, 0, nullptr, &p) == S_OK) - { - result = p; - } - CoTaskMemFree(static_cast(p)); + wchar_t* p{ nullptr }; + if (SHGetKnownFolderPath(FOLDERID_Music, 0, nullptr, &p) == S_OK) + { + result = p; + } + CoTaskMemFree(static_cast(p)); #elif defined(__linux__) - result = getXDGDir("XDG_MUSIC_DIR"); - result = result.empty() ? (getHome() / "Music") : result; + result = getXDGDir("XDG_MUSIC_DIR"); + result = result.empty() ? (getHome() / "Music") : result; #endif - std::filesystem::create_directories(result); - return result; - } + std::filesystem::create_directories(result); + return result; + } - std::filesystem::path UserDirectories::getPictures() - { - std::filesystem::path result; + std::filesystem::path UserDirectories::getPictures() + { + std::filesystem::path result; #ifdef _WIN32 - wchar_t* p{ nullptr }; - if (SHGetKnownFolderPath(FOLDERID_Pictures, 0, nullptr, &p) == S_OK) - { - result = p; - } - CoTaskMemFree(static_cast(p)); + wchar_t* p{ nullptr }; + if (SHGetKnownFolderPath(FOLDERID_Pictures, 0, nullptr, &p) == S_OK) + { + result = p; + } + CoTaskMemFree(static_cast(p)); #elif defined(__linux__) - result = getXDGDir("XDG_PICTURES_DIR"); - result = result.empty() ? (getHome() / "Pictures") : result; + result = getXDGDir("XDG_PICTURES_DIR"); + result = result.empty() ? (getHome() / "Pictures") : result; #endif - std::filesystem::create_directories(result); - return result; - } + std::filesystem::create_directories(result); + return result; + } - std::filesystem::path UserDirectories::getPublicShare() - { - std::filesystem::path result; + std::filesystem::path UserDirectories::getPublicShare() + { + std::filesystem::path result; #ifdef __linux__ - result = getXDGDir("XDG_PUBLICSHARE_DIR"); + result = getXDGDir("XDG_PUBLICSHARE_DIR"); #endif - return result; - } + return result; + } - std::filesystem::path UserDirectories::getTemplates() - { - std::filesystem::path result; + std::filesystem::path UserDirectories::getTemplates() + { + std::filesystem::path result; #ifdef _WIN32 - wchar_t* p{ nullptr }; - if (SHGetKnownFolderPath(FOLDERID_Templates, 0, nullptr, &p) == S_OK) - { - result = p; - } - CoTaskMemFree(static_cast(p)); + wchar_t* p{ nullptr }; + if (SHGetKnownFolderPath(FOLDERID_Templates, 0, nullptr, &p) == S_OK) + { + result = p; + } + CoTaskMemFree(static_cast(p)); #elif defined(__linux__) - result = getXDGDir("XDG_TEMPLATES_DIR"); - result = result.empty() ? (getHome() / "Templates") : result; + result = getXDGDir("XDG_TEMPLATES_DIR"); + result = result.empty() ? (getHome() / "Templates") : result; #endif - std::filesystem::create_directories(result); - return result; - } + std::filesystem::create_directories(result); + return result; + } - std::filesystem::path UserDirectories::getVideos() - { - std::filesystem::path result; + std::filesystem::path UserDirectories::getVideos() + { + std::filesystem::path result; #ifdef _WIN32 - wchar_t* p{ nullptr }; - if (SHGetKnownFolderPath(FOLDERID_Videos, 0, nullptr, &p) == S_OK) - { - result = p; - } - CoTaskMemFree(static_cast(p)); + wchar_t* p{ nullptr }; + if (SHGetKnownFolderPath(FOLDERID_Videos, 0, nullptr, &p) == S_OK) + { + result = p; + } + CoTaskMemFree(static_cast(p)); #elif defined(__linux__) - result = getXDGDir("XDG_VIDEOS_DIR"); - result = result.empty() ? (getHome() / "Videos") : result; + result = getXDGDir("XDG_VIDEOS_DIR"); + result = result.empty() ? (getHome() / "Videos") : result; #endif - std::filesystem::create_directories(result); - return result; - } + std::filesystem::create_directories(result); + return result; + } } \ No newline at end of file diff --git a/src/helpers/webhelpers.cpp b/src/helpers/webhelpers.cpp index 47282d2..f62bb8a 100644 --- a/src/helpers/webhelpers.cpp +++ b/src/helpers/webhelpers.cpp @@ -3,106 +3,106 @@ namespace Nickvision { - bool WebHelpers::downloadFile(const std::string& url, const std::filesystem::path& path, const CurlProgressFunction& progress, bool overwrite) - { - if (url.empty()) - { - return false; - } - if (std::filesystem::exists(path) && !overwrite) - { - return false; - } - CURL* curl{ curl_easy_init() }; - if (!curl) - { - return false; - } - std::ofstream out{ path, std::ios::binary | std::ios::trunc }; - curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); - curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, true); - curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, +[](char* ptr, size_t size, size_t nmemb, void* data) - { - std::ofstream* stream{ static_cast(data) }; - stream->write(ptr, size * nmemb); - return size * nmemb; - }); - curl_easy_setopt(curl, CURLOPT_WRITEDATA, &out); + bool WebHelpers::downloadFile(const std::string& url, const std::filesystem::path& path, const CurlProgressFunction& progress, bool overwrite) + { + if (url.empty()) + { + return false; + } + if (std::filesystem::exists(path) && !overwrite) + { + return false; + } + CURL* curl{ curl_easy_init() }; + if (!curl) + { + return false; + } + std::ofstream out{ path, std::ios::binary | std::ios::trunc }; + curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); + curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, true); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, +[](char* ptr, size_t size, size_t nmemb, void* data) + { + std::ofstream* stream{ static_cast(data) }; + stream->write(ptr, size * nmemb); + return size * nmemb; + }); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, &out); #ifdef _WIN32 - curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0); - curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0); #endif - if (progress) - { - curl_easy_setopt(curl, CURLOPT_NOPROGRESS, false); - curl_easy_setopt(curl, CURLOPT_XFERINFODATA, &progress); - curl_easy_setopt(curl, CURLOPT_XFERINFOFUNCTION, +[](void* data, curl_off_t dltotal, curl_off_t dlnow, curl_off_t ultotal, curl_off_t ulnow) - { - CurlProgressFunction& func{ *(static_cast(data)) }; - return func(dltotal, dlnow, ultotal, ulnow); - }); - } - CURLcode code{ curl_easy_perform(curl) }; - curl_easy_cleanup(curl); - return code == CURLE_OK; - } + if (progress) + { + curl_easy_setopt(curl, CURLOPT_NOPROGRESS, false); + curl_easy_setopt(curl, CURLOPT_XFERINFODATA, &progress); + curl_easy_setopt(curl, CURLOPT_XFERINFOFUNCTION, +[](void* data, curl_off_t dltotal, curl_off_t dlnow, curl_off_t ultotal, curl_off_t ulnow) + { + CurlProgressFunction& func{ *(static_cast(data)) }; + return func(dltotal, dlnow, ultotal, ulnow); + }); + } + CURLcode code{ curl_easy_perform(curl) }; + curl_easy_cleanup(curl); + return code == CURLE_OK; + } - std::string WebHelpers::fetchJsonString(const std::string& url) - { - if (url.empty()) - { - return ""; - } - CURL* curl{ curl_easy_init() }; - if (!curl) - { - return ""; - } - std::stringstream out; - struct curl_slist* listHttpHeader{ curl_slist_append(nullptr, "Content-Type: application/json") }; - curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); - curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, true); - curl_easy_setopt(curl, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/120.0"); - curl_easy_setopt(curl, CURLOPT_HTTPHEADER, listHttpHeader); - curl_easy_setopt(curl, CURLOPT_HEADER, false); - curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, +[](char* ptr, size_t size, size_t nmemb, void* data) - { - std::stringstream* stream{ static_cast(data) }; - stream->write(ptr, size * nmemb); - return size * nmemb; - }); - curl_easy_setopt(curl, CURLOPT_WRITEDATA, &out); + std::string WebHelpers::fetchJsonString(const std::string& url) + { + if (url.empty()) + { + return ""; + } + CURL* curl{ curl_easy_init() }; + if (!curl) + { + return ""; + } + std::stringstream out; + struct curl_slist* listHttpHeader{ curl_slist_append(nullptr, "Content-Type: application/json") }; + curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); + curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, true); + curl_easy_setopt(curl, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/120.0"); + curl_easy_setopt(curl, CURLOPT_HTTPHEADER, listHttpHeader); + curl_easy_setopt(curl, CURLOPT_HEADER, false); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, +[](char* ptr, size_t size, size_t nmemb, void* data) + { + std::stringstream* stream{ static_cast(data) }; + stream->write(ptr, size * nmemb); + return size * nmemb; + }); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, &out); #ifdef _WIN32 - curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0); - curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0); #endif - CURLcode code{ curl_easy_perform(curl) }; - curl_easy_cleanup(curl); - curl_slist_free_all(listHttpHeader); - return code == CURLE_OK ? out.str() : ""; - } + CURLcode code{ curl_easy_perform(curl) }; + curl_easy_cleanup(curl); + curl_slist_free_all(listHttpHeader); + return code == CURLE_OK ? out.str() : ""; + } - bool WebHelpers::isValidWebsite(const std::string& url) - { - if (url.empty()) - { - return false; - } - CURL* curl{ curl_easy_init() }; - if (!curl) - { - return false; - } - curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); - curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, true); - curl_easy_setopt(curl, CURLOPT_NOBODY, 1); - curl_easy_setopt(curl, CURLOPT_HEADER, false); + bool WebHelpers::isValidWebsite(const std::string& url) + { + if (url.empty()) + { + return false; + } + CURL* curl{ curl_easy_init() }; + if (!curl) + { + return false; + } + curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); + curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, true); + curl_easy_setopt(curl, CURLOPT_NOBODY, 1); + curl_easy_setopt(curl, CURLOPT_HEADER, false); #ifdef _WIN32 - curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0); - curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0); #endif - CURLcode code{ curl_easy_perform(curl) }; - curl_easy_cleanup(curl); - return code == CURLE_OK; - } + CURLcode code{ curl_easy_perform(curl) }; + curl_easy_cleanup(curl); + return code == CURLE_OK; + } } \ No newline at end of file diff --git a/src/keyring/credential.cpp b/src/keyring/credential.cpp index 04de0c8..3dea212 100644 --- a/src/keyring/credential.cpp +++ b/src/keyring/credential.cpp @@ -4,98 +4,98 @@ namespace Nickvision::Keyring { - Credential::Credential(int id, const std::string& name, const std::string& uri, const std::string& username, const std::string& password) - : m_id{ id }, - m_name{ name }, - m_uri{ uri }, - m_username{ username }, - m_password{ password } - { - - } - - Credential::Credential(const std::string& name, const std::string& uri, const std::string& username, const std::string& password) - : m_id{ static_cast(std::hash{}(StringHelpers::newGuid())) }, - m_name{ name }, - m_uri{ uri }, - m_username{ username }, - m_password{ password } - { - - } - - int Credential::getId() const - { - return m_id; - } - - const std::string& Credential::getName() const - { - return m_name; - } - - void Credential::setName(const std::string& name) - { - m_name = name; - } - - const std::string& Credential::getUri() const - { - return m_uri; - } - - void Credential::setUri(const std::string& uri) - { - m_uri = uri; - } - - const std::string& Credential::getUsername() const - { - return m_username; - } - - void Credential::setUsername(const std::string& username) - { - m_username = username; - } - - const std::string& Credential::getPassword() const - { - return m_password; - } - - void Credential::setPassword(const std::string& password) - { - m_password = password; - } - - bool Credential::operator<(const Credential& compare) const - { - return m_id < compare.m_id; - } - - bool Credential::operator>(const Credential& compare) const - { - return m_id > compare.m_id; - } - - bool Credential::operator==(const Credential& compare) const - { - return m_id == compare.m_id; - } - - bool Credential::operator!=(const Credential& compare) const - { - return m_id != compare.m_id; - } - - std::ostream& operator<<(std::ostream& os, const Credential& credential) - { - os << "[CRED: " << credential.getName() << "] " << std::endl; - os << "Uri: " << credential.getUri() << std::endl; - os << "Username: " << credential.getUsername() << std::endl; - os << "Password: " << credential.getPassword() << std::endl; - os << "Strength: " << (int)getPasswordStrength(credential.getPassword()) << std::endl; - return os; - } + Credential::Credential(int id, const std::string& name, const std::string& uri, const std::string& username, const std::string& password) + : m_id{ id }, + m_name{ name }, + m_uri{ uri }, + m_username{ username }, + m_password{ password } + { + + } + + Credential::Credential(const std::string& name, const std::string& uri, const std::string& username, const std::string& password) + : m_id{ static_cast(std::hash{}(StringHelpers::newGuid())) }, + m_name{ name }, + m_uri{ uri }, + m_username{ username }, + m_password{ password } + { + + } + + int Credential::getId() const + { + return m_id; + } + + const std::string& Credential::getName() const + { + return m_name; + } + + void Credential::setName(const std::string& name) + { + m_name = name; + } + + const std::string& Credential::getUri() const + { + return m_uri; + } + + void Credential::setUri(const std::string& uri) + { + m_uri = uri; + } + + const std::string& Credential::getUsername() const + { + return m_username; + } + + void Credential::setUsername(const std::string& username) + { + m_username = username; + } + + const std::string& Credential::getPassword() const + { + return m_password; + } + + void Credential::setPassword(const std::string& password) + { + m_password = password; + } + + bool Credential::operator<(const Credential& compare) const + { + return m_id < compare.m_id; + } + + bool Credential::operator>(const Credential& compare) const + { + return m_id > compare.m_id; + } + + bool Credential::operator==(const Credential& compare) const + { + return m_id == compare.m_id; + } + + bool Credential::operator!=(const Credential& compare) const + { + return m_id != compare.m_id; + } + + std::ostream& operator<<(std::ostream& os, const Credential& credential) + { + os << "[CRED: " << credential.getName() << "] " << std::endl; + os << "Uri: " << credential.getUri() << std::endl; + os << "Username: " << credential.getUsername() << std::endl; + os << "Password: " << credential.getPassword() << std::endl; + os << "Strength: " << (int)getPasswordStrength(credential.getPassword()) << std::endl; + return os; + } } \ No newline at end of file diff --git a/src/keyring/keyring.cpp b/src/keyring/keyring.cpp index b2ec132..64bfc33 100644 --- a/src/keyring/keyring.cpp +++ b/src/keyring/keyring.cpp @@ -3,100 +3,100 @@ namespace Nickvision::Keyring { - Keyring::Keyring(const Store& store) - : m_store{ store } - { + Keyring::Keyring(const Store& store) + : m_store{ store } + { - } + } - const std::string& Keyring::getName() const - { - return m_store.getName(); - } + const std::string& Keyring::getName() const + { + return m_store.getName(); + } - std::vector Keyring::getAllCredentials() const - { - return m_store.getAllCredentials(); - } + std::vector Keyring::getAllCredentials() const + { + return m_store.getAllCredentials(); + } - std::optional Keyring::getCredential(int id) const - { - return m_store.getCredential(id); - } + std::optional Keyring::getCredential(int id) const + { + return m_store.getCredential(id); + } - std::vector Keyring::getCredentials(const std::string& name) const - { - return m_store.getCredentials(name); - } + std::vector Keyring::getCredentials(const std::string& name) const + { + return m_store.getCredentials(name); + } - bool Keyring::addCredential(const Credential& credential) - { - return m_store.addCredential(credential); - } + bool Keyring::addCredential(const Credential& credential) + { + return m_store.addCredential(credential); + } - bool Keyring::updateCredential(const Credential& credential) - { - return m_store.updateCredential(credential); - } + bool Keyring::updateCredential(const Credential& credential) + { + return m_store.updateCredential(credential); + } - bool Keyring::deleteCredential(int id) - { - return m_store.deleteCredential(id); - } + bool Keyring::deleteCredential(int id) + { + return m_store.deleteCredential(id); + } - bool Keyring::destroy() - { - if (m_store.destroy()) - { - SystemCredentials::deleteCredential(m_store.getName()); //keyring's password may not be in system credentials - return true; - } - return false; - } + bool Keyring::destroy() + { + if (m_store.destroy()) + { + SystemCredentials::deleteCredential(m_store.getName()); //keyring's password may not be in system credentials + return true; + } + return false; + } - std::optional Keyring::access(const std::string& name, std::string password) - { - //If password empty, get password from system credential store - if (password.empty()) - { - std::optional cred{ SystemCredentials::getCredential(name) }; - if (cred.has_value()) - { - password = cred->getPassword(); - } - else - { - cred = SystemCredentials::addCredential(name); - password = cred ? cred->getPassword() : ""; - } - } - //If password not empty (a.k.a user-provided or system-provided), get store - if (!password.empty()) - { - try - { - return { { { name, password } } }; - } - catch (...) - { - return std::nullopt; - } - } - return std::nullopt; - } + std::optional Keyring::access(const std::string& name, std::string password) + { + //If password empty, get password from system credential store + if (password.empty()) + { + std::optional cred{ SystemCredentials::getCredential(name) }; + if (cred.has_value()) + { + password = cred->getPassword(); + } + else + { + cred = SystemCredentials::addCredential(name); + password = cred ? cred->getPassword() : ""; + } + } + //If password not empty (a.k.a user-provided or system-provided), get store + if (!password.empty()) + { + try + { + return { { { name, password } } }; + } + catch (...) + { + return std::nullopt; + } + } + return std::nullopt; + } - bool Keyring::exists(const std::string& name) - { - return Store::exists(name); - } + bool Keyring::exists(const std::string& name) + { + return Store::exists(name); + } - bool Keyring::destroy(const std::string& name) - { - if (Store::destroy(name)) - { - SystemCredentials::deleteCredential(name); //keyring's password may not be in system credentials - return true; - } - return false; - } + bool Keyring::destroy(const std::string& name) + { + if (Store::destroy(name)) + { + SystemCredentials::deleteCredential(name); //keyring's password may not be in system credentials + return true; + } + return false; + } } \ No newline at end of file diff --git a/src/keyring/keyringdialogcontroller.cpp b/src/keyring/keyringdialogcontroller.cpp index 0eda6b8..df5e80e 100644 --- a/src/keyring/keyringdialogcontroller.cpp +++ b/src/keyring/keyringdialogcontroller.cpp @@ -3,116 +3,116 @@ namespace Nickvision::Keyring { - KeyringDialogController::KeyringDialogController(const std::string& name, const std::optional& keyring) - : m_name{ name }, - m_keyring{ keyring } - { + KeyringDialogController::KeyringDialogController(const std::string& name, const std::optional& keyring) + : m_name{ name }, + m_keyring{ keyring } + { - } + } - const std::optional& KeyringDialogController::getKeyring() - { - return m_keyring; - } + const std::optional& KeyringDialogController::getKeyring() + { + return m_keyring; + } - bool KeyringDialogController::isEnabled() const - { - return m_keyring.has_value(); - } + bool KeyringDialogController::isEnabled() const + { + return m_keyring.has_value(); + } - bool KeyringDialogController::isValid() const - { - return !(!m_keyring && Keyring::exists(m_name)); - } + bool KeyringDialogController::isValid() const + { + return !(!m_keyring && Keyring::exists(m_name)); + } - bool KeyringDialogController::enableKeyring(const std::string& password) - { - if (!m_keyring) - { - m_keyring = Keyring::access(m_name, password); - return m_keyring.has_value(); - } - return false; - } + bool KeyringDialogController::enableKeyring(const std::string& password) + { + if (!m_keyring) + { + m_keyring = Keyring::access(m_name, password); + return m_keyring.has_value(); + } + return false; + } - bool KeyringDialogController::disableKeyring() - { - if (m_keyring) - { - bool res{ m_keyring->destroy() }; - m_keyring = std::nullopt; - return res; - } - return false; - } + bool KeyringDialogController::disableKeyring() + { + if (m_keyring) + { + bool res{ m_keyring->destroy() }; + m_keyring = std::nullopt; + return res; + } + return false; + } - bool KeyringDialogController::resetKeyring() - { - if (!m_keyring) - { - return Keyring::destroy(m_name); - } - return false; - } + bool KeyringDialogController::resetKeyring() + { + if (!m_keyring) + { + return Keyring::destroy(m_name); + } + return false; + } - CredentialCheckStatus KeyringDialogController::validateCredential(const Credential& credential) const - { - CredentialCheckStatus result = (CredentialCheckStatus)0; - if (credential.getName().empty()) - { - result |= CredentialCheckStatus::EmptyName; - } - if (credential.getUsername().empty() && credential.getPassword().empty()) - { - result |= CredentialCheckStatus::EmptyUsernamePassword; - } - if (!credential.getUri().empty() && !StringHelpers::isValidUrl(credential.getUri())) - { - result |= CredentialCheckStatus::InvalidUri; - } - if ((int)result != 0) - { - return result; - } - return CredentialCheckStatus::Valid; - } + CredentialCheckStatus KeyringDialogController::validateCredential(const Credential& credential) const + { + CredentialCheckStatus result = (CredentialCheckStatus)0; + if (credential.getName().empty()) + { + result |= CredentialCheckStatus::EmptyName; + } + if (credential.getUsername().empty() && credential.getPassword().empty()) + { + result |= CredentialCheckStatus::EmptyUsernamePassword; + } + if (!credential.getUri().empty() && !StringHelpers::isValidUrl(credential.getUri())) + { + result |= CredentialCheckStatus::InvalidUri; + } + if ((int)result != 0) + { + return result; + } + return CredentialCheckStatus::Valid; + } - std::vector KeyringDialogController::getAllCredentials() const - { - if (m_keyring) - { - return m_keyring->getAllCredentials(); - } - return {}; - } + std::vector KeyringDialogController::getAllCredentials() const + { + if (m_keyring) + { + return m_keyring->getAllCredentials(); + } + return {}; + } - bool KeyringDialogController::addCredential(const Credential& credential) - { - if (m_keyring && (validateCredential(credential) & CredentialCheckStatus::Valid) == CredentialCheckStatus::Valid) - { - return m_keyring->addCredential(credential); - } - return false; - } + bool KeyringDialogController::addCredential(const Credential& credential) + { + if (m_keyring && (validateCredential(credential) & CredentialCheckStatus::Valid) == CredentialCheckStatus::Valid) + { + return m_keyring->addCredential(credential); + } + return false; + } - bool KeyringDialogController::updateCredential(const Credential& credential) - { - if (m_keyring && (validateCredential(credential) & CredentialCheckStatus::Valid) == CredentialCheckStatus::Valid) - { - if (m_keyring->getCredential(credential.getId())) - { - return m_keyring->updateCredential(credential); - } - } - return false; - } + bool KeyringDialogController::updateCredential(const Credential& credential) + { + if (m_keyring && (validateCredential(credential) & CredentialCheckStatus::Valid) == CredentialCheckStatus::Valid) + { + if (m_keyring->getCredential(credential.getId())) + { + return m_keyring->updateCredential(credential); + } + } + return false; + } - bool KeyringDialogController::deleteCredential(int id) - { - if (m_keyring) - { - return m_keyring->deleteCredential(id); - } - return false; - } + bool KeyringDialogController::deleteCredential(int id) + { + if (m_keyring) + { + return m_keyring->deleteCredential(id); + } + return false; + } } \ No newline at end of file diff --git a/src/keyring/passwordgenerator.cpp b/src/keyring/passwordgenerator.cpp index a982b42..15e6d26 100644 --- a/src/keyring/passwordgenerator.cpp +++ b/src/keyring/passwordgenerator.cpp @@ -4,51 +4,51 @@ namespace Nickvision::Keyring { - std::vector PasswordGenerator::m_numericChars = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' }; - std::vector PasswordGenerator::m_upperChars = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' }; - std::vector PasswordGenerator::m_lowerChars = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z' }; - std::vector PasswordGenerator::m_specialChars = { '!', '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.', '/', ':', ';', '<', '=', '>', '?', '@', '[', '\\', ']', '^', '_', '`', '{', '|', '}', '~' }; + std::vector PasswordGenerator::m_numericChars = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' }; + std::vector PasswordGenerator::m_upperChars = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' }; + std::vector PasswordGenerator::m_lowerChars = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z' }; + std::vector PasswordGenerator::m_specialChars = { '!', '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.', '/', ':', ';', '<', '=', '>', '?', '@', '[', '\\', ']', '^', '_', '`', '{', '|', '}', '~' }; - PasswordGenerator::PasswordGenerator(PasswordContent contentFlags) - { - srand((unsigned)time(0)); - setContentFlags(contentFlags); - } + PasswordGenerator::PasswordGenerator(PasswordContent contentFlags) + { + srand((unsigned)time(0)); + setContentFlags(contentFlags); + } - PasswordContent PasswordGenerator::getContentFlags() const - { - return m_contentFlags; - } + PasswordContent PasswordGenerator::getContentFlags() const + { + return m_contentFlags; + } - void PasswordGenerator::setContentFlags(PasswordContent contentFlags) - { - m_contentFlags = contentFlags; - m_chars.clear(); - if ((m_contentFlags & PasswordContent::Numeric) == PasswordContent::Numeric) - { - m_chars.insert(m_chars.end(), m_numericChars.begin(), m_numericChars.end()); - } - if ((m_contentFlags & PasswordContent::Uppercase) == PasswordContent::Uppercase) - { - m_chars.insert(m_chars.end(), m_upperChars.begin(), m_upperChars.end()); - } - if ((m_contentFlags & PasswordContent::Lowercase) == PasswordContent::Lowercase) - { - m_chars.insert(m_chars.end(), m_lowerChars.begin(), m_lowerChars.end()); - } - if ((m_contentFlags & PasswordContent::Special) == PasswordContent::Special) - { - m_chars.insert(m_chars.end(), m_specialChars.begin(), m_specialChars.end()); - } - } + void PasswordGenerator::setContentFlags(PasswordContent contentFlags) + { + m_contentFlags = contentFlags; + m_chars.clear(); + if ((m_contentFlags & PasswordContent::Numeric) == PasswordContent::Numeric) + { + m_chars.insert(m_chars.end(), m_numericChars.begin(), m_numericChars.end()); + } + if ((m_contentFlags & PasswordContent::Uppercase) == PasswordContent::Uppercase) + { + m_chars.insert(m_chars.end(), m_upperChars.begin(), m_upperChars.end()); + } + if ((m_contentFlags & PasswordContent::Lowercase) == PasswordContent::Lowercase) + { + m_chars.insert(m_chars.end(), m_lowerChars.begin(), m_lowerChars.end()); + } + if ((m_contentFlags & PasswordContent::Special) == PasswordContent::Special) + { + m_chars.insert(m_chars.end(), m_specialChars.begin(), m_specialChars.end()); + } + } - std::string PasswordGenerator::next(size_t length) - { - std::string pass; + std::string PasswordGenerator::next(size_t length) + { + std::string pass; for(size_t i = 0; i < length; i++) { pass += m_chars[rand() % m_chars.size()]; } return pass; - } + } } \ No newline at end of file diff --git a/src/keyring/passwordstrength.cpp b/src/keyring/passwordstrength.cpp index cf84f67..b6f2208 100644 --- a/src/keyring/passwordstrength.cpp +++ b/src/keyring/passwordstrength.cpp @@ -2,48 +2,48 @@ namespace Nickvision::Keyring { - PasswordStrength getPasswordStrength(const std::string& password) - { - if (password.empty()) - { - return PasswordStrength::Blank; - } - if (password.size() <= 6) - { - return PasswordStrength::VeryWeak; - } - int strength{ 0 }; - bool containsDigit = false; - bool containsLower = false; - bool containsUpper = false; - bool containsSymbol = false; - if (password.size() >= 12) - { - strength++; - } - for (char ch : password) - { - if (!containsDigit && std::isdigit(ch)) - { - strength++; - containsDigit = true; - } - if (!containsLower && std::isalpha(ch) && std::islower(ch)) - { - strength++; - containsLower = true; - } - if (!containsUpper && std::isalpha(ch) && std::isupper(ch)) - { - strength++; - containsUpper = true; - } - if (!containsSymbol && !std::isalnum(ch)) - { - strength++; - containsSymbol = true; - } - } - return (PasswordStrength)strength; - } + PasswordStrength getPasswordStrength(const std::string& password) + { + if (password.empty()) + { + return PasswordStrength::Blank; + } + if (password.size() <= 6) + { + return PasswordStrength::VeryWeak; + } + int strength{ 0 }; + bool containsDigit = false; + bool containsLower = false; + bool containsUpper = false; + bool containsSymbol = false; + if (password.size() >= 12) + { + strength++; + } + for (char ch : password) + { + if (!containsDigit && std::isdigit(ch)) + { + strength++; + containsDigit = true; + } + if (!containsLower && std::isalpha(ch) && std::islower(ch)) + { + strength++; + containsLower = true; + } + if (!containsUpper && std::isalpha(ch) && std::isupper(ch)) + { + strength++; + containsUpper = true; + } + if (!containsSymbol && !std::isalnum(ch)) + { + strength++; + containsSymbol = true; + } + } + return (PasswordStrength)strength; + } } \ No newline at end of file diff --git a/src/keyring/store.cpp b/src/keyring/store.cpp index eceee33..807ece6 100644 --- a/src/keyring/store.cpp +++ b/src/keyring/store.cpp @@ -6,278 +6,278 @@ using namespace Nickvision::Filesystem; namespace Nickvision::Keyring { - static std::filesystem::path getPathFromName(const std::string& name) - { - std::filesystem::path dir{ UserDirectories::getConfig() / "Nickvision" / "Keyring" }; - std::filesystem::create_directories(dir); - return dir / (name + ".ring"); - } + static std::filesystem::path getPathFromName(const std::string& name) + { + std::filesystem::path dir{ UserDirectories::getConfig() / "Nickvision" / "Keyring" }; + std::filesystem::create_directories(dir); + return dir / (name + ".ring"); + } - Store::Store(const std::string& name, const std::string& password) - : m_name{ name }, - m_password{ password }, - m_database{ nullptr }, - m_path{ getPathFromName(name) } - { - sqlite3* database{ nullptr }; - char* err{ nullptr }; - if (sqlite3_open_v2(m_path.string().c_str(), &database, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, nullptr) == SQLITE_OK) - { - if (sqlite3_key(database, m_password.c_str(), static_cast(m_password.size())) == SQLITE_OK) - { - if (sqlite3_exec(database, "CREATE TABLE IF NOT EXISTS credentials (id TEXT PRIMARY KEY, name TEXT, uri TEXT, username TEXT, password TEXT)", nullptr, nullptr, &err) == SQLITE_OK) - { - m_database = { database, [](sqlite3* sql) - { - sqlite3_close(sql); - }}; - return; - } - else - { - std::string error{ err ? err : "" }; - sqlite3_free(err); - sqlite3_close(database); - throw std::runtime_error("Unable to exec create table command. Key may be invalid. " + error); - } - } - else - { - sqlite3_close(database); - throw std::runtime_error("Unable to key the database."); - } - } - else - { - throw std::runtime_error("Unable to open the database."); - } - } + Store::Store(const std::string& name, const std::string& password) + : m_name{ name }, + m_password{ password }, + m_database{ nullptr }, + m_path{ getPathFromName(name) } + { + sqlite3* database{ nullptr }; + char* err{ nullptr }; + if (sqlite3_open_v2(m_path.string().c_str(), &database, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, nullptr) == SQLITE_OK) + { + if (sqlite3_key(database, m_password.c_str(), static_cast(m_password.size())) == SQLITE_OK) + { + if (sqlite3_exec(database, "CREATE TABLE IF NOT EXISTS credentials (id TEXT PRIMARY KEY, name TEXT, uri TEXT, username TEXT, password TEXT)", nullptr, nullptr, &err) == SQLITE_OK) + { + m_database = { database, [](sqlite3* sql) + { + sqlite3_close(sql); + }}; + return; + } + else + { + std::string error{ err ? err : "" }; + sqlite3_free(err); + sqlite3_close(database); + throw std::runtime_error("Unable to exec create table command. Key may be invalid. " + error); + } + } + else + { + sqlite3_close(database); + throw std::runtime_error("Unable to key the database."); + } + } + else + { + throw std::runtime_error("Unable to open the database."); + } + } - Store::Store(const Store& store) - { - std::lock_guard lock{ store.m_mutex }; - m_name = store.m_name; - m_password = store.m_password; - m_database = store.m_database; - m_path = store.m_path; - } + Store::Store(const Store& store) + { + std::lock_guard lock{ store.m_mutex }; + m_name = store.m_name; + m_password = store.m_password; + m_database = store.m_database; + m_path = store.m_path; + } - Store::Store(Store&& store) noexcept - { - std::lock_guard lock{ store.m_mutex }; - m_name = std::move(store.m_name); - m_password = std::move(store.m_password); - m_database = std::move(store.m_database); - m_path = std::move(store.m_path); - } + Store::Store(Store&& store) noexcept + { + std::lock_guard lock{ store.m_mutex }; + m_name = std::move(store.m_name); + m_password = std::move(store.m_password); + m_database = std::move(store.m_database); + m_path = std::move(store.m_path); + } - const std::string& Store::getName() const - { - std::lock_guard lock{ m_mutex }; - return m_name; - } + const std::string& Store::getName() const + { + std::lock_guard lock{ m_mutex }; + return m_name; + } - const std::filesystem::path& Store::getPath() const - { - std::lock_guard lock{ m_mutex }; - return m_path; - } + const std::filesystem::path& Store::getPath() const + { + std::lock_guard lock{ m_mutex }; + return m_path; + } - std::vector Store::getAllCredentials() const - { - std::lock_guard lock{ m_mutex }; - std::vector creds; - if (m_database) - { - sqlite3_stmt* statement; - if (sqlite3_prepare_v2(m_database.get(), "SELECT * FROM credentials", -1, &statement, nullptr) == SQLITE_OK) - { - while (sqlite3_step(statement) == SQLITE_ROW) - { - creds.push_back({ sqlite3_column_int(statement, 0), (const char*)sqlite3_column_text(statement, 1), (const char*)sqlite3_column_text(statement, 2), (const char*)sqlite3_column_text(statement, 3), (const char*)sqlite3_column_text(statement, 4) }); - } - sqlite3_finalize(statement); - } - } - return creds; - } + std::vector Store::getAllCredentials() const + { + std::lock_guard lock{ m_mutex }; + std::vector creds; + if (m_database) + { + sqlite3_stmt* statement; + if (sqlite3_prepare_v2(m_database.get(), "SELECT * FROM credentials", -1, &statement, nullptr) == SQLITE_OK) + { + while (sqlite3_step(statement) == SQLITE_ROW) + { + creds.push_back({ sqlite3_column_int(statement, 0), (const char*)sqlite3_column_text(statement, 1), (const char*)sqlite3_column_text(statement, 2), (const char*)sqlite3_column_text(statement, 3), (const char*)sqlite3_column_text(statement, 4) }); + } + sqlite3_finalize(statement); + } + } + return creds; + } - std::optional Store::getCredential(int id) const - { - std::lock_guard lock{ m_mutex }; - std::optional cred{ std::nullopt }; - if (m_database) - { - sqlite3_stmt* statement; - if (sqlite3_prepare_v2(m_database.get(), "SELECT * FROM credentials where id = ?", -1, &statement, nullptr) == SQLITE_OK) - { - if (sqlite3_bind_int(statement, 1, id) == SQLITE_OK) - { - if (sqlite3_step(statement) == SQLITE_ROW) - { - cred = { { sqlite3_column_int(statement, 0), (const char*)sqlite3_column_text(statement, 1), (const char*)sqlite3_column_text(statement, 2), (const char*)sqlite3_column_text(statement, 3), (const char*)sqlite3_column_text(statement, 4) } }; - } - } - sqlite3_finalize(statement); - } - } - return cred; - } + std::optional Store::getCredential(int id) const + { + std::lock_guard lock{ m_mutex }; + std::optional cred{ std::nullopt }; + if (m_database) + { + sqlite3_stmt* statement; + if (sqlite3_prepare_v2(m_database.get(), "SELECT * FROM credentials where id = ?", -1, &statement, nullptr) == SQLITE_OK) + { + if (sqlite3_bind_int(statement, 1, id) == SQLITE_OK) + { + if (sqlite3_step(statement) == SQLITE_ROW) + { + cred = { { sqlite3_column_int(statement, 0), (const char*)sqlite3_column_text(statement, 1), (const char*)sqlite3_column_text(statement, 2), (const char*)sqlite3_column_text(statement, 3), (const char*)sqlite3_column_text(statement, 4) } }; + } + } + sqlite3_finalize(statement); + } + } + return cred; + } - std::vector Store::getCredentials(const std::string& name) const - { - std::lock_guard lock{ m_mutex }; - std::vector creds; - if (m_database) - { - sqlite3_stmt* statement; - if (sqlite3_prepare_v2(m_database.get(), "SELECT * FROM credentials where name = ?", -1, &statement, nullptr) == SQLITE_OK) - { - if (sqlite3_bind_text(statement, 1, name.c_str(), -1, SQLITE_TRANSIENT) == SQLITE_OK) - { - while (sqlite3_step(statement) == SQLITE_ROW) - { - creds.push_back({ sqlite3_column_int(statement, 0), (const char*)sqlite3_column_text(statement, 1), (const char*)sqlite3_column_text(statement, 2), (const char*)sqlite3_column_text(statement, 3), (const char*)sqlite3_column_text(statement, 4) }); - } - } - sqlite3_finalize(statement); - } - } - return creds; - } + std::vector Store::getCredentials(const std::string& name) const + { + std::lock_guard lock{ m_mutex }; + std::vector creds; + if (m_database) + { + sqlite3_stmt* statement; + if (sqlite3_prepare_v2(m_database.get(), "SELECT * FROM credentials where name = ?", -1, &statement, nullptr) == SQLITE_OK) + { + if (sqlite3_bind_text(statement, 1, name.c_str(), -1, SQLITE_TRANSIENT) == SQLITE_OK) + { + while (sqlite3_step(statement) == SQLITE_ROW) + { + creds.push_back({ sqlite3_column_int(statement, 0), (const char*)sqlite3_column_text(statement, 1), (const char*)sqlite3_column_text(statement, 2), (const char*)sqlite3_column_text(statement, 3), (const char*)sqlite3_column_text(statement, 4) }); + } + } + sqlite3_finalize(statement); + } + } + return creds; + } - bool Store::addCredential(const Credential& credential) - { - std::lock_guard lock{ m_mutex }; - bool res{ false }; - if (m_database) - { - sqlite3_stmt* statement; - if (sqlite3_prepare_v2(m_database.get(), "INSERT INTO credentials (id, name, uri, username, password) VALUES (?,?,?,?,?)", -1, &statement, nullptr) == SQLITE_OK) - { - if (sqlite3_bind_int(statement, 1, credential.getId()) == SQLITE_OK) - { - if (sqlite3_bind_text(statement, 2, credential.getName().c_str(), -1, SQLITE_TRANSIENT) == SQLITE_OK) - { - if (sqlite3_bind_text(statement, 3, credential.getUri().c_str(), -1, SQLITE_TRANSIENT) == SQLITE_OK) - { - if (sqlite3_bind_text(statement, 4, credential.getUsername().c_str(), -1, SQLITE_TRANSIENT) == SQLITE_OK) - { - if (sqlite3_bind_text(statement, 5, credential.getPassword().c_str(), -1, SQLITE_TRANSIENT) == SQLITE_OK) - { - res = sqlite3_step(statement) == SQLITE_DONE; - } - } - } - } - } - sqlite3_finalize(statement); - } - } - return res; - } + bool Store::addCredential(const Credential& credential) + { + std::lock_guard lock{ m_mutex }; + bool res{ false }; + if (m_database) + { + sqlite3_stmt* statement; + if (sqlite3_prepare_v2(m_database.get(), "INSERT INTO credentials (id, name, uri, username, password) VALUES (?,?,?,?,?)", -1, &statement, nullptr) == SQLITE_OK) + { + if (sqlite3_bind_int(statement, 1, credential.getId()) == SQLITE_OK) + { + if (sqlite3_bind_text(statement, 2, credential.getName().c_str(), -1, SQLITE_TRANSIENT) == SQLITE_OK) + { + if (sqlite3_bind_text(statement, 3, credential.getUri().c_str(), -1, SQLITE_TRANSIENT) == SQLITE_OK) + { + if (sqlite3_bind_text(statement, 4, credential.getUsername().c_str(), -1, SQLITE_TRANSIENT) == SQLITE_OK) + { + if (sqlite3_bind_text(statement, 5, credential.getPassword().c_str(), -1, SQLITE_TRANSIENT) == SQLITE_OK) + { + res = sqlite3_step(statement) == SQLITE_DONE; + } + } + } + } + } + sqlite3_finalize(statement); + } + } + return res; + } - bool Store::updateCredential(const Credential& credential) - { - std::lock_guard lock{ m_mutex }; - bool res{ false }; - if (m_database) - { - sqlite3_stmt* statement; - if (sqlite3_prepare_v2(m_database.get(), "UPDATE credentials SET name = ?, uri = ?, username = ?, password = ? where id = ?", -1, &statement, nullptr) == SQLITE_OK) - { - if (sqlite3_bind_int(statement, 5, credential.getId()) == SQLITE_OK) - { - if (sqlite3_bind_text(statement, 1, credential.getName().c_str(), -1, SQLITE_TRANSIENT) == SQLITE_OK) - { - if (sqlite3_bind_text(statement, 2, credential.getUri().c_str(), -1, SQLITE_TRANSIENT) == SQLITE_OK) - { - if (sqlite3_bind_text(statement, 3, credential.getUsername().c_str(), -1, SQLITE_TRANSIENT) == SQLITE_OK) - { - if (sqlite3_bind_text(statement, 4, credential.getPassword().c_str(), -1, SQLITE_TRANSIENT) == SQLITE_OK) - { - res = sqlite3_step(statement) == SQLITE_DONE; - } - } - } - } - } - sqlite3_finalize(statement); - } - } - return res; - } + bool Store::updateCredential(const Credential& credential) + { + std::lock_guard lock{ m_mutex }; + bool res{ false }; + if (m_database) + { + sqlite3_stmt* statement; + if (sqlite3_prepare_v2(m_database.get(), "UPDATE credentials SET name = ?, uri = ?, username = ?, password = ? where id = ?", -1, &statement, nullptr) == SQLITE_OK) + { + if (sqlite3_bind_int(statement, 5, credential.getId()) == SQLITE_OK) + { + if (sqlite3_bind_text(statement, 1, credential.getName().c_str(), -1, SQLITE_TRANSIENT) == SQLITE_OK) + { + if (sqlite3_bind_text(statement, 2, credential.getUri().c_str(), -1, SQLITE_TRANSIENT) == SQLITE_OK) + { + if (sqlite3_bind_text(statement, 3, credential.getUsername().c_str(), -1, SQLITE_TRANSIENT) == SQLITE_OK) + { + if (sqlite3_bind_text(statement, 4, credential.getPassword().c_str(), -1, SQLITE_TRANSIENT) == SQLITE_OK) + { + res = sqlite3_step(statement) == SQLITE_DONE; + } + } + } + } + } + sqlite3_finalize(statement); + } + } + return res; + } - bool Store::deleteCredential(int id) - { - std::lock_guard lock{ m_mutex }; - bool res{ false }; - if (m_database) - { - sqlite3_stmt* statement; - if (sqlite3_prepare_v2(m_database.get(), "DELETE FROM credentials WHERE id = ?", -1, &statement, nullptr) == SQLITE_OK) - { - if (sqlite3_bind_int(statement, 1, id) == SQLITE_OK) - { - res = sqlite3_step(statement) == SQLITE_DONE; - } - sqlite3_finalize(statement); - } - } - return res; - } + bool Store::deleteCredential(int id) + { + std::lock_guard lock{ m_mutex }; + bool res{ false }; + if (m_database) + { + sqlite3_stmt* statement; + if (sqlite3_prepare_v2(m_database.get(), "DELETE FROM credentials WHERE id = ?", -1, &statement, nullptr) == SQLITE_OK) + { + if (sqlite3_bind_int(statement, 1, id) == SQLITE_OK) + { + res = sqlite3_step(statement) == SQLITE_DONE; + } + sqlite3_finalize(statement); + } + } + return res; + } - bool Store::destroy() - { - std::lock_guard lock{ m_mutex }; - if (m_database) - { - sqlite3_close(m_database.get()); - m_database = nullptr; - } - return std::filesystem::exists(m_path) ? std::filesystem::remove(m_path) : true; - } + bool Store::destroy() + { + std::lock_guard lock{ m_mutex }; + if (m_database) + { + sqlite3_close(m_database.get()); + m_database = nullptr; + } + return std::filesystem::exists(m_path) ? std::filesystem::remove(m_path) : true; + } - Store& Store::operator=(const Store& store) - { - if (this != &store) - { - std::lock_guard lock{ m_mutex }; - std::lock_guard lock2{ store.m_mutex }; - m_name = store.m_name; - m_password = store.m_password; - m_database = store.m_database; - m_path = store.m_path; - } - return *this; - } + Store& Store::operator=(const Store& store) + { + if (this != &store) + { + std::lock_guard lock{ m_mutex }; + std::lock_guard lock2{ store.m_mutex }; + m_name = store.m_name; + m_password = store.m_password; + m_database = store.m_database; + m_path = store.m_path; + } + return *this; + } - Store& Store::operator=(Store&& store) noexcept - { - if (this != &store) - { - std::lock_guard lock{ m_mutex }; - std::lock_guard lock2{ store.m_mutex }; - m_name = std::move(store.m_name); - m_password = std::move(store.m_password); - m_database = std::move(store.m_database); - m_path = std::move(store.m_path); - } - return *this; - } + Store& Store::operator=(Store&& store) noexcept + { + if (this != &store) + { + std::lock_guard lock{ m_mutex }; + std::lock_guard lock2{ store.m_mutex }; + m_name = std::move(store.m_name); + m_password = std::move(store.m_password); + m_database = std::move(store.m_database); + m_path = std::move(store.m_path); + } + return *this; + } - bool Store::exists(const std::string& name) - { - return std::filesystem::exists(getPathFromName(name)); - } + bool Store::exists(const std::string& name) + { + return std::filesystem::exists(getPathFromName(name)); + } - bool Store::destroy(const std::string& name) - { - std::filesystem::path path{ getPathFromName(name) }; - if (std::filesystem::exists(path)) - { - return std::filesystem::remove(path); - } - return true; - } + bool Store::destroy(const std::string& name) + { + std::filesystem::path path{ getPathFromName(name) }; + if (std::filesystem::exists(path)) + { + return std::filesystem::remove(path); + } + return true; + } } \ No newline at end of file diff --git a/src/keyring/systemcredentials.cpp b/src/keyring/systemcredentials.cpp index af6b1b7..a257f52 100644 --- a/src/keyring/systemcredentials.cpp +++ b/src/keyring/systemcredentials.cpp @@ -11,138 +11,138 @@ namespace Nickvision::Keyring { #ifdef __linux__ - static const SecretSchema KEYRING_SCHEMA = { "org.nickvision.aura.keyring", SECRET_SCHEMA_NONE, { { "application", SECRET_SCHEMA_ATTRIBUTE_STRING }, { "NULL", SECRET_SCHEMA_ATTRIBUTE_STRING } } }; + static const SecretSchema KEYRING_SCHEMA = { "org.nickvision.aura.keyring", SECRET_SCHEMA_NONE, { { "application", SECRET_SCHEMA_ATTRIBUTE_STRING }, { "NULL", SECRET_SCHEMA_ATTRIBUTE_STRING } } }; #endif - std::optional SystemCredentials::getCredential(const std::string& name) - { + std::optional SystemCredentials::getCredential(const std::string& name) + { #ifdef _WIN32 - CREDENTIALA* cred{ nullptr }; - if (CredReadA(name.c_str(), CRED_TYPE_GENERIC, 0, &cred)) - { - if (cred->CredentialBlob) - { - std::string credName{ cred->TargetName ? cred->TargetName : "" }; - std::string credUrl{ cred->Comment ? cred->Comment : "" }; - std::string credUsername{ cred->UserName ? cred->UserName : "" }; - std::string credPassword{ LPCSTR(cred->CredentialBlob), cred->CredentialBlobSize }; - CredFree(cred); - return { { credName, credUrl, credUsername, credPassword } }; - } - } + CREDENTIALA* cred{ nullptr }; + if (CredReadA(name.c_str(), CRED_TYPE_GENERIC, 0, &cred)) + { + if (cred->CredentialBlob) + { + std::string credName{ cred->TargetName ? cred->TargetName : "" }; + std::string credUrl{ cred->Comment ? cred->Comment : "" }; + std::string credUsername{ cred->UserName ? cred->UserName : "" }; + std::string credPassword{ LPCSTR(cred->CredentialBlob), cred->CredentialBlobSize }; + CredFree(cred); + return { { credName, credUrl, credUsername, credPassword } }; + } + } #elif defined(__linux__) - GError* error{ nullptr }; - char* password{ secret_password_lookup_sync(&KEYRING_SCHEMA, nullptr, &error, "application", name.c_str(), NULL) }; - if (!error && password) - { - Credential c{ name, "", "default", password }; - secret_password_free(password); - return c; - } - if (error) - { - g_error_free(error); - } + GError* error{ nullptr }; + char* password{ secret_password_lookup_sync(&KEYRING_SCHEMA, nullptr, &error, "application", name.c_str(), NULL) }; + if (!error && password) + { + Credential c{ name, "", "default", password }; + secret_password_free(password); + return c; + } + if (error) + { + g_error_free(error); + } #endif - return std::nullopt; - } + return std::nullopt; + } - std::optional SystemCredentials::addCredential(const std::string& name) - { - PasswordGenerator passGen; - Credential c{ name, "", "default", passGen.next() }; - if (addCredential(c)) - { - return c; - } - return std::nullopt; - } + std::optional SystemCredentials::addCredential(const std::string& name) + { + PasswordGenerator passGen; + Credential c{ name, "", "default", passGen.next() }; + if (addCredential(c)) + { + return c; + } + return std::nullopt; + } - bool SystemCredentials::addCredential(const Credential& credential) - { + bool SystemCredentials::addCredential(const Credential& credential) + { #ifdef _WIN32 - CREDENTIALA* cred{ new CREDENTIALA() }; - cred->AttributeCount = 0; - cred->Attributes = nullptr; - cred->Comment = nullptr; - cred->Type = CRED_TYPE_GENERIC; - cred->Persist = CRED_PERSIST_LOCAL_MACHINE; - cred->TargetName = LPSTR(credential.getName().c_str()); - cred->UserName = LPSTR(credential.getUsername().c_str()); - cred->CredentialBlobSize = (unsigned long)credential.getPassword().size(); - cred->CredentialBlob = LPBYTE(credential.getPassword().c_str()); - bool res = CredWriteA(cred, 0); - CredFree(cred); - return res; + CREDENTIALA* cred{ new CREDENTIALA() }; + cred->AttributeCount = 0; + cred->Attributes = nullptr; + cred->Comment = nullptr; + cred->Type = CRED_TYPE_GENERIC; + cred->Persist = CRED_PERSIST_LOCAL_MACHINE; + cred->TargetName = LPSTR(credential.getName().c_str()); + cred->UserName = LPSTR(credential.getUsername().c_str()); + cred->CredentialBlobSize = (unsigned long)credential.getPassword().size(); + cred->CredentialBlob = LPBYTE(credential.getPassword().c_str()); + bool res = CredWriteA(cred, 0); + CredFree(cred); + return res; #elif defined(__linux__) - GError* error{ nullptr }; - secret_password_store_sync(&KEYRING_SCHEMA, SECRET_COLLECTION_DEFAULT, credential.getName().c_str(), credential.getPassword().c_str(), nullptr, &error, "application", credential.getName().c_str(), NULL); - if (error) - { - g_error_free(error); - return false; - } - return true; + GError* error{ nullptr }; + secret_password_store_sync(&KEYRING_SCHEMA, SECRET_COLLECTION_DEFAULT, credential.getName().c_str(), credential.getPassword().c_str(), nullptr, &error, "application", credential.getName().c_str(), NULL); + if (error) + { + g_error_free(error); + return false; + } + return true; #endif - } + } - bool SystemCredentials::updateCredential(const Credential& credential) - { + bool SystemCredentials::updateCredential(const Credential& credential) + { #ifdef _WIN32 - CREDENTIALA* cred{ nullptr }; - if (CredReadA(credential.getName().c_str(), CRED_TYPE_GENERIC, 0, &cred)) - { - cred->AttributeCount = 0; - cred->Attributes = nullptr; - cred->Comment = nullptr; - cred->Type = CRED_TYPE_GENERIC; - cred->Persist = CRED_PERSIST_LOCAL_MACHINE; - cred->TargetName = LPSTR(credential.getName().c_str()); - cred->UserName = LPSTR(credential.getUsername().c_str()); - cred->CredentialBlobSize = (unsigned long)credential.getPassword().size(); - cred->CredentialBlob = LPBYTE(credential.getPassword().c_str()); - bool res = CredWriteA(cred, 0); - CredFree(cred); - return res; - } + CREDENTIALA* cred{ nullptr }; + if (CredReadA(credential.getName().c_str(), CRED_TYPE_GENERIC, 0, &cred)) + { + cred->AttributeCount = 0; + cred->Attributes = nullptr; + cred->Comment = nullptr; + cred->Type = CRED_TYPE_GENERIC; + cred->Persist = CRED_PERSIST_LOCAL_MACHINE; + cred->TargetName = LPSTR(credential.getName().c_str()); + cred->UserName = LPSTR(credential.getUsername().c_str()); + cred->CredentialBlobSize = (unsigned long)credential.getPassword().size(); + cred->CredentialBlob = LPBYTE(credential.getPassword().c_str()); + bool res = CredWriteA(cred, 0); + CredFree(cred); + return res; + } #elif defined(__linux__) - GError* error{ nullptr }; - char* password{ secret_password_lookup_sync(&KEYRING_SCHEMA, nullptr, &error, "application", credential.getName().c_str(), NULL) }; - if (!error && password) - { - secret_password_free(password); - secret_password_store_sync(&KEYRING_SCHEMA, SECRET_COLLECTION_DEFAULT, credential.getName().c_str(), credential.getPassword().c_str(), nullptr, &error, "application", credential.getName().c_str(), NULL); - if (error) - { - g_error_free(error); - return false; - } - return true; - } - if (error) - { - g_error_free(error); - } + GError* error{ nullptr }; + char* password{ secret_password_lookup_sync(&KEYRING_SCHEMA, nullptr, &error, "application", credential.getName().c_str(), NULL) }; + if (!error && password) + { + secret_password_free(password); + secret_password_store_sync(&KEYRING_SCHEMA, SECRET_COLLECTION_DEFAULT, credential.getName().c_str(), credential.getPassword().c_str(), nullptr, &error, "application", credential.getName().c_str(), NULL); + if (error) + { + g_error_free(error); + return false; + } + return true; + } + if (error) + { + g_error_free(error); + } #endif - return false; - } - - bool SystemCredentials::deleteCredential(const std::string& name) - { + return false; + } + + bool SystemCredentials::deleteCredential(const std::string& name) + { #ifdef _WIN32 - return CredDeleteA(name.c_str(), CRED_TYPE_GENERIC, 0); + return CredDeleteA(name.c_str(), CRED_TYPE_GENERIC, 0); #elif defined(__linux__) - GError* error{ nullptr }; - bool res{ secret_password_clear_sync(&KEYRING_SCHEMA, nullptr, &error, "application", name.c_str(), NULL) }; - if (!error) - { - return res; - } - if (error) - { - g_error_free(error); - } - return false; + GError* error{ nullptr }; + bool res{ secret_password_clear_sync(&KEYRING_SCHEMA, nullptr, &error, "application", name.c_str(), NULL) }; + if (!error) + { + return res; + } + if (error) + { + g_error_free(error); + } + return false; #endif - } + } } \ No newline at end of file diff --git a/src/localization/documentation.cpp b/src/localization/documentation.cpp index d46d7d6..37ce9a7 100644 --- a/src/localization/documentation.cpp +++ b/src/localization/documentation.cpp @@ -21,11 +21,11 @@ namespace Nickvision::Localization if (!sysLocale.empty() && sysLocale != "C" && sysLocale != "en_US") { /* - * Because the translations of a Nickvision application are stored in the application's running - * directory, we can look at the list of directory names and see if they contain a translation - * file (.mo). If a directory contains an mo file, we can add that directory name (which is a - * language code) to the list of available translated languages for the app. - */ + * Because the translations of a Nickvision application are stored in the application's running + * directory, we can look at the list of directory names and see if they contain a translation + * file (.mo). If a directory contains an mo file, we can add that directory name (which is a + * language code) to the list of available translated languages for the app. + */ std::vector langs; for (const std::filesystem::directory_entry& e : std::filesystem::directory_iterator(Aura::getActive().getExecutableDirectory())) { diff --git a/src/localization/gettext.cpp b/src/localization/gettext.cpp index 00fc3b0..e482d52 100644 --- a/src/localization/gettext.cpp +++ b/src/localization/gettext.cpp @@ -7,51 +7,51 @@ using namespace Nickvision::App; namespace Nickvision::Localization { - static std::string m_domainName; + static std::string m_domainName; - bool Gettext::init(const std::string& domainName) - { - static bool initialized{ false }; - if(!initialized) - { - bool res{ true }; - setlocale(LC_ALL, ""); - m_domainName = domainName; + bool Gettext::init(const std::string& domainName) + { + static bool initialized{ false }; + if(!initialized) + { + bool res{ true }; + setlocale(LC_ALL, ""); + m_domainName = domainName; #ifdef _WIN32 - res = res && (wbindtextdomain(m_domainName.c_str(), Aura::getActive().getExecutableDirectory().c_str()) != nullptr); + res = res && (wbindtextdomain(m_domainName.c_str(), Aura::getActive().getExecutableDirectory().c_str()) != nullptr); #elif defined(__linux__) - res = res && (bindtextdomain(m_domainName.c_str(), Aura::getActive().getExecutableDirectory().c_str()) != nullptr); - res = res && (bind_textdomain_codeset(m_domainName.c_str(), "UTF-8") != nullptr); + res = res && (bindtextdomain(m_domainName.c_str(), Aura::getActive().getExecutableDirectory().c_str()) != nullptr); + res = res && (bind_textdomain_codeset(m_domainName.c_str(), "UTF-8") != nullptr); #endif - res = res && (textdomain(m_domainName.c_str()) != nullptr); - initialized = true; - return res; - } - return true; - } + res = res && (textdomain(m_domainName.c_str()) != nullptr); + initialized = true; + return res; + } + return true; + } - const std::string& Gettext::getDomainName() - { - return m_domainName; - } + const std::string& Gettext::getDomainName() + { + return m_domainName; + } - const char* Gettext::pgettext(const char* context, const char* msg) - { - const char* translation{ dcgettext(m_domainName.c_str(), context, LC_MESSAGES) }; - if (translation == context) - { - return msg; - } - return translation; - } + const char* Gettext::pgettext(const char* context, const char* msg) + { + const char* translation{ dcgettext(m_domainName.c_str(), context, LC_MESSAGES) }; + if (translation == context) + { + return msg; + } + return translation; + } - const char* Gettext::pngettext(const char* context, const char* msg, const char* msgPlural, unsigned long n) - { - const char* translation{ dcngettext(m_domainName.c_str(), context, msgPlural, n, LC_MESSAGES) }; - if (translation == context || translation == msgPlural) - { - return n == 1 ? msg : msgPlural; - } - return translation; - } + const char* Gettext::pngettext(const char* context, const char* msg, const char* msgPlural, unsigned long n) + { + const char* translation{ dcngettext(m_domainName.c_str(), context, msgPlural, n, LC_MESSAGES) }; + if (translation == context || translation == msgPlural) + { + return n == 1 ? msg : msgPlural; + } + return translation; + } } \ No newline at end of file diff --git a/src/network/networkmonitor.cpp b/src/network/networkmonitor.cpp index 914c57a..290c38d 100644 --- a/src/network/networkmonitor.cpp +++ b/src/network/networkmonitor.cpp @@ -11,165 +11,165 @@ using namespace Nickvision::App; namespace Nickvision::Network { #ifdef _WIN32 - class NetworkListManagerEvents : INetworkListManagerEvents - { - public: - NetworkListManagerEvents(NetworkMonitor* netmon) - : m_netmon{ netmon } - { + class NetworkListManagerEvents : INetworkListManagerEvents + { + public: + NetworkListManagerEvents(NetworkMonitor* netmon) + : m_netmon{ netmon } + { - } + } - ULONG AddRef() - { - return 1L; - } + ULONG AddRef() + { + return 1L; + } - ULONG Release() - { - return 1L; - } + ULONG Release() + { + return 1L; + } - HRESULT QueryInterface(REFIID riid, LPVOID* ppvObj) - { - if (!ppvObj) - { - return E_POINTER; - } - *ppvObj = nullptr; - if (riid == IID_IUnknown || riid == IID_INetworkListManagerEvents) - { - AddRef(); - *ppvObj = reinterpret_cast(this); - return S_OK; - } - return E_NOINTERFACE; - } + HRESULT QueryInterface(REFIID riid, LPVOID* ppvObj) + { + if (!ppvObj) + { + return E_POINTER; + } + *ppvObj = nullptr; + if (riid == IID_IUnknown || riid == IID_INetworkListManagerEvents) + { + AddRef(); + *ppvObj = reinterpret_cast(this); + return S_OK; + } + return E_NOINTERFACE; + } - HRESULT ConnectivityChanged(NLM_CONNECTIVITY) - { - m_netmon->checkConnectionState(); - return S_OK; - } + HRESULT ConnectivityChanged(NLM_CONNECTIVITY) + { + m_netmon->checkConnectionState(); + return S_OK; + } - HRESULT NetworkConnectionPropertyChanged(GUID, NLM_CONNECTION_PROPERTY_CHANGE) - { - return S_OK; - } + HRESULT NetworkConnectionPropertyChanged(GUID, NLM_CONNECTION_PROPERTY_CHANGE) + { + return S_OK; + } - private: - NetworkMonitor* m_netmon; - }; + private: + NetworkMonitor* m_netmon; + }; #endif - NetworkMonitor::NetworkMonitor() - : m_connectionState{ NetworkState::Disconnected } - { + NetworkMonitor::NetworkMonitor() + : m_connectionState{ NetworkState::Disconnected } + { #ifdef _WIN32 - CoInitializeEx(nullptr, COINIT_MULTITHREADED); - m_netListManagerEvents = new NetworkListManagerEvents(this); - if (CoCreateInstance(CLSID_NetworkListManager, nullptr, CLSCTX_ALL, __uuidof(INetworkListManager), (LPVOID*)&m_netListManager) != S_OK) - { - throw std::runtime_error("Unable to create network list manager."); - } - if (m_netListManager->QueryInterface(IID_PPV_ARGS(&m_connectionPointContainer)) != S_OK) - { - throw std::runtime_error("Unable to create connection point container."); - } - if (m_connectionPointContainer->FindConnectionPoint(IID_INetworkListManagerEvents, &m_connectionPoint) != S_OK) - { - throw std::runtime_error("Unable to find connection point."); - } - if (reinterpret_cast(m_netListManagerEvents)->QueryInterface(IID_IUnknown, reinterpret_cast(&m_sink)) != S_OK) - { - throw std::runtime_error("Unable to get sink pointer."); - } - if (m_connectionPoint->Advise(m_sink, &m_cookie) != S_OK) - { - throw std::runtime_error("Unable to get advice connection point."); - } + CoInitializeEx(nullptr, COINIT_MULTITHREADED); + m_netListManagerEvents = new NetworkListManagerEvents(this); + if (CoCreateInstance(CLSID_NetworkListManager, nullptr, CLSCTX_ALL, __uuidof(INetworkListManager), (LPVOID*)&m_netListManager) != S_OK) + { + throw std::runtime_error("Unable to create network list manager."); + } + if (m_netListManager->QueryInterface(IID_PPV_ARGS(&m_connectionPointContainer)) != S_OK) + { + throw std::runtime_error("Unable to create connection point container."); + } + if (m_connectionPointContainer->FindConnectionPoint(IID_INetworkListManagerEvents, &m_connectionPoint) != S_OK) + { + throw std::runtime_error("Unable to find connection point."); + } + if (reinterpret_cast(m_netListManagerEvents)->QueryInterface(IID_IUnknown, reinterpret_cast(&m_sink)) != S_OK) + { + throw std::runtime_error("Unable to get sink pointer."); + } + if (m_connectionPoint->Advise(m_sink, &m_cookie) != S_OK) + { + throw std::runtime_error("Unable to get advice connection point."); + } #elif defined(__linux__) - m_networkChangedHandlerId = g_signal_connect_data(G_OBJECT(g_network_monitor_get_default()), "network-changed", G_CALLBACK((void(*)(GNetworkMonitor*, bool, void*))([](GNetworkMonitor*, bool, void* data) - { - static_cast(data)->checkConnectionState(); - })), this, nullptr, G_CONNECT_DEFAULT); - if (m_networkChangedHandlerId <= 0) - { - throw std::runtime_error("Unable to connect to network monitor signal."); - } + m_networkChangedHandlerId = g_signal_connect_data(G_OBJECT(g_network_monitor_get_default()), "network-changed", G_CALLBACK((void(*)(GNetworkMonitor*, bool, void*))([](GNetworkMonitor*, bool, void* data) + { + static_cast(data)->checkConnectionState(); + })), this, nullptr, G_CONNECT_DEFAULT); + if (m_networkChangedHandlerId <= 0) + { + throw std::runtime_error("Unable to connect to network monitor signal."); + } #endif - checkConnectionState(); - } + checkConnectionState(); + } - NetworkMonitor::~NetworkMonitor() - { + NetworkMonitor::~NetworkMonitor() + { #ifdef _WIN32 - m_connectionPoint->Unadvise(m_cookie); - delete reinterpret_cast(m_netListManagerEvents); + m_connectionPoint->Unadvise(m_cookie); + delete reinterpret_cast(m_netListManagerEvents); #elif defined(__linux__) - g_signal_handler_disconnect(G_OBJECT(g_network_monitor_get_default()), m_networkChangedHandlerId); + g_signal_handler_disconnect(G_OBJECT(g_network_monitor_get_default()), m_networkChangedHandlerId); #endif - } + } - Events::Event& NetworkMonitor::stateChanged() - { - return m_stateChanged; - } + Events::Event& NetworkMonitor::stateChanged() + { + return m_stateChanged; + } - NetworkState NetworkMonitor::getConnectionState() const - { - std::lock_guard lock{ m_mutex }; - return m_connectionState; - } + NetworkState NetworkMonitor::getConnectionState() const + { + std::lock_guard lock{ m_mutex }; + return m_connectionState; + } - void NetworkMonitor::checkConnectionState() - { - std::lock_guard lock{ m_mutex }; - NetworkState newState{ NetworkState::Disconnected }; - std::string noNetCheck{ StringHelpers::toLower(Aura::getActive().getEnvVar("AURA_DISABLE_NETCHECK")) }; - if (!noNetCheck.empty() && (noNetCheck == "true" || noNetCheck == "t" || noNetCheck == "yes" || noNetCheck == "y" || noNetCheck == "1")) - { - newState = NetworkState::ConnectedGlobal; - } - else - { + void NetworkMonitor::checkConnectionState() + { + std::lock_guard lock{ m_mutex }; + NetworkState newState{ NetworkState::Disconnected }; + std::string noNetCheck{ StringHelpers::toLower(Aura::getActive().getEnvVar("AURA_DISABLE_NETCHECK")) }; + if (!noNetCheck.empty() && (noNetCheck == "true" || noNetCheck == "t" || noNetCheck == "yes" || noNetCheck == "y" || noNetCheck == "1")) + { + newState = NetworkState::ConnectedGlobal; + } + else + { #ifdef _WIN32 - NLM_CONNECTIVITY connection{ NLM_CONNECTIVITY_DISCONNECTED }; - if (m_netListManager->GetConnectivity(&connection) == S_OK) - { - if (connection == NLM_CONNECTIVITY_DISCONNECTED) - { - newState = NetworkState::Disconnected; - } - else if (connection & NLM_CONNECTIVITY_IPV4_INTERNET || connection & NLM_CONNECTIVITY_IPV6_INTERNET) - { - newState = NetworkState::ConnectedGlobal; - } - else - { - newState = NetworkState::ConnectedLocal; - } - } + NLM_CONNECTIVITY connection{ NLM_CONNECTIVITY_DISCONNECTED }; + if (m_netListManager->GetConnectivity(&connection) == S_OK) + { + if (connection == NLM_CONNECTIVITY_DISCONNECTED) + { + newState = NetworkState::Disconnected; + } + else if (connection & NLM_CONNECTIVITY_IPV4_INTERNET || connection & NLM_CONNECTIVITY_IPV6_INTERNET) + { + newState = NetworkState::ConnectedGlobal; + } + else + { + newState = NetworkState::ConnectedLocal; + } + } #elif defined(__linux__) - GNetworkConnectivity connection{ g_network_monitor_get_connectivity(g_network_monitor_get_default()) }; - if (connection == G_NETWORK_CONNECTIVITY_LOCAL) - { - newState = NetworkState::Disconnected; - } - else if (connection == G_NETWORK_CONNECTIVITY_FULL) - { - newState = NetworkState::ConnectedGlobal; - } - else - { - newState = NetworkState::ConnectedLocal; - } + GNetworkConnectivity connection{ g_network_monitor_get_connectivity(g_network_monitor_get_default()) }; + if (connection == G_NETWORK_CONNECTIVITY_LOCAL) + { + newState = NetworkState::Disconnected; + } + else if (connection == G_NETWORK_CONNECTIVITY_FULL) + { + newState = NetworkState::ConnectedGlobal; + } + else + { + newState = NetworkState::ConnectedLocal; + } #endif - } - if (m_connectionState != newState) - { - m_connectionState = newState; - m_stateChanged({ m_connectionState }); - } - } + } + if (m_connectionState != newState) + { + m_connectionState = newState; + m_stateChanged({ m_connectionState }); + } + } } \ No newline at end of file diff --git a/src/network/networkstatechangedeventargs.cpp b/src/network/networkstatechangedeventargs.cpp index 6b3e821..4091dc7 100644 --- a/src/network/networkstatechangedeventargs.cpp +++ b/src/network/networkstatechangedeventargs.cpp @@ -2,14 +2,14 @@ namespace Nickvision::Network { - NetworkStateChangedEventArgs::NetworkStateChangedEventArgs(NetworkState state) - : m_state{ state } - { + NetworkStateChangedEventArgs::NetworkStateChangedEventArgs(NetworkState state) + : m_state{ state } + { - } + } - NetworkState NetworkStateChangedEventArgs::getState() const - { - return m_state; - } + NetworkState NetworkStateChangedEventArgs::getState() const + { + return m_state; + } } \ No newline at end of file diff --git a/src/notifications/notificationsenteventargs.cpp b/src/notifications/notificationsenteventargs.cpp index fa0a401..894484d 100644 --- a/src/notifications/notificationsenteventargs.cpp +++ b/src/notifications/notificationsenteventargs.cpp @@ -2,32 +2,32 @@ namespace Nickvision::Notifications { - NotificationSentEventArgs::NotificationSentEventArgs(const std::string& message, NotificationSeverity severity, const std::string& action, const std::string& actionParam) - : m_message{ message }, - m_severity{ severity }, - m_action{ action }, - m_actionParam{ actionParam } - { + NotificationSentEventArgs::NotificationSentEventArgs(const std::string& message, NotificationSeverity severity, const std::string& action, const std::string& actionParam) + : m_message{ message }, + m_severity{ severity }, + m_action{ action }, + m_actionParam{ actionParam } + { - } + } - const std::string& NotificationSentEventArgs::getMessage() const - { - return m_message; - } + const std::string& NotificationSentEventArgs::getMessage() const + { + return m_message; + } - NotificationSeverity NotificationSentEventArgs::getSeverity() const - { - return m_severity; - } + NotificationSeverity NotificationSentEventArgs::getSeverity() const + { + return m_severity; + } - const std::string& NotificationSentEventArgs::getAction() const - { - return m_action; - } + const std::string& NotificationSentEventArgs::getAction() const + { + return m_action; + } - const std::string& NotificationSentEventArgs::getActionParam() const - { - return m_actionParam; - } + const std::string& NotificationSentEventArgs::getActionParam() const + { + return m_actionParam; + } } \ No newline at end of file diff --git a/src/notifications/notifyicon.cpp b/src/notifications/notifyicon.cpp index 61739ec..a58d50b 100644 --- a/src/notifications/notifyicon.cpp +++ b/src/notifications/notifyicon.cpp @@ -9,261 +9,261 @@ using namespace Nickvision::App; namespace Nickvision::Notifications { - std::map NotifyIcon::m_icons = {}; + std::map NotifyIcon::m_icons = {}; - NotifyIcon::NotifyIcon(HWND hwnd, const NotifyIconMenu& contextMenu, bool hidden) - : m_className{ StringHelpers::newGuid() }, - m_isHidden{ hidden }, - m_tooltip{ Aura::getActive().getAppInfo().getName() }, - m_contextMenu{ contextMenu }, - m_hwnd{ nullptr } - { - CoInitializeEx(nullptr, COINIT_MULTITHREADED); - HICON icon{ (HICON)GetClassLongPtrA(hwnd, GCLP_HICON) }; - if (!icon) - { - SHSTOCKICONINFO info{ 0 }; - info.cbSize = sizeof(info); - if (SHGetStockIconInfo(SIID_APPLICATION, SHGSI_ICON, &info) == S_OK) - { - icon = info.hIcon; - } - } - HICON smallIcon{ (HICON)GetClassLongPtrA(hwnd, GCLP_HICONSM) }; - if (!smallIcon) - { - SHSTOCKICONINFO info{ 0 }; - info.cbSize = sizeof(info); - if (SHGetStockIconInfo(SIID_APPLICATION, SHGSI_ICON | SHGSI_SMALLICON, &info) == S_OK) - { - icon = info.hIcon; - } - } - //Create a window for the NotifyIcon - WNDCLASSEXA windowClass; - windowClass.cbSize = sizeof(windowClass); - windowClass.style = CS_GLOBALCLASS; - windowClass.lpfnWndProc = NotifyIcon::notifyIconWindowProc; - windowClass.cbClsExtra = 0; - windowClass.cbWndExtra = 0; - windowClass.hInstance = nullptr; - windowClass.hIcon = icon; - windowClass.hCursor = LoadCursor(nullptr, IDC_ARROW);; - windowClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); - windowClass.lpszMenuName = 0; - windowClass.lpszClassName = m_className.c_str(); - windowClass.hIconSm = smallIcon; - ATOM registeredClass{ RegisterClassExA(&windowClass) }; - if (registeredClass == 0) - { - throw std::runtime_error("Unable to register window class: " + std::to_string(GetLastError()) + "."); - } - m_hwnd = CreateWindowExA(0, m_className.c_str(), "AuraNotifyIcon", WS_CHILD, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, hwnd, nullptr, nullptr, nullptr); - if (!m_hwnd) - { - throw std::runtime_error("Unable to create window: " + std::to_string(GetLastError()) + "."); - } - m_icons.insert({ m_hwnd, this }); - //Create the NotifyIcon - if (CoCreateGuid(&m_guid) != S_OK) - { - throw std::runtime_error("Unable to create guid: " + std::to_string(GetLastError()) + "."); - } - NOTIFYICONDATAA notify{ getBaseNotifyIconData() }; - notify.uFlags |= NIF_ICON | NIF_TIP; - notify.hIcon = icon; - StringCchCopyA(notify.szTip, ARRAYSIZE(notify.szTip), m_tooltip.c_str()); - notify.uVersion = NOTIFYICON_VERSION_4; - if (!Shell_NotifyIconA(NIM_ADD, ¬ify)) - { - throw std::runtime_error("Unable to create NotifyIcon: " + std::to_string(GetLastError()) + "."); - } - Shell_NotifyIconA(NIM_SETVERSION, ¬ify); - //Create context menu - if (!m_contextMenu.empty()) - { - m_hmenu = CreatePopupMenu(); - if (!m_hmenu) - { - throw std::runtime_error("Unable to create menu: " + std::to_string(GetLastError()) + "."); - } - for (size_t i = 0; i < m_contextMenu.size(); i++) - { - const std::shared_ptr& item{ m_contextMenu.get(i) }; - if (item->getType() == NotifyIconMenuItemType::Action) - { - const NotifyIconActionMenuItem* action{ static_cast(item.get()) }; - MENUITEMINFOA actionItem{ 0 }; - actionItem.cbSize = sizeof(actionItem); - actionItem.fMask = MIIM_ID | MIIM_FTYPE | MIIM_STRING; - actionItem.fType = MFT_STRING; - actionItem.wID = static_cast(IDM_CONTEXT_MENU + i); - actionItem.dwTypeData = LPSTR(action->getLabel().c_str()); - actionItem.cch = static_cast(action->getLabel().size()); - InsertMenuItemA(m_hmenu, static_cast(i), TRUE, &actionItem); - } - else if (item->getType() == NotifyIconMenuItemType::Separator) - { - MENUITEMINFOA separatorItem{ 0 }; - separatorItem.cbSize = sizeof(separatorItem); - separatorItem.fMask = MIIM_ID | MIIM_FTYPE; - separatorItem.fType = MFT_SEPARATOR; - separatorItem.wID = static_cast(IDM_CONTEXT_MENU + i); - InsertMenuItemA(m_hmenu, static_cast(i), TRUE, &separatorItem); - } - } - } - } + NotifyIcon::NotifyIcon(HWND hwnd, const NotifyIconMenu& contextMenu, bool hidden) + : m_className{ StringHelpers::newGuid() }, + m_isHidden{ hidden }, + m_tooltip{ Aura::getActive().getAppInfo().getName() }, + m_contextMenu{ contextMenu }, + m_hwnd{ nullptr } + { + CoInitializeEx(nullptr, COINIT_MULTITHREADED); + HICON icon{ (HICON)GetClassLongPtrA(hwnd, GCLP_HICON) }; + if (!icon) + { + SHSTOCKICONINFO info{ 0 }; + info.cbSize = sizeof(info); + if (SHGetStockIconInfo(SIID_APPLICATION, SHGSI_ICON, &info) == S_OK) + { + icon = info.hIcon; + } + } + HICON smallIcon{ (HICON)GetClassLongPtrA(hwnd, GCLP_HICONSM) }; + if (!smallIcon) + { + SHSTOCKICONINFO info{ 0 }; + info.cbSize = sizeof(info); + if (SHGetStockIconInfo(SIID_APPLICATION, SHGSI_ICON | SHGSI_SMALLICON, &info) == S_OK) + { + icon = info.hIcon; + } + } + //Create a window for the NotifyIcon + WNDCLASSEXA windowClass; + windowClass.cbSize = sizeof(windowClass); + windowClass.style = CS_GLOBALCLASS; + windowClass.lpfnWndProc = NotifyIcon::notifyIconWindowProc; + windowClass.cbClsExtra = 0; + windowClass.cbWndExtra = 0; + windowClass.hInstance = nullptr; + windowClass.hIcon = icon; + windowClass.hCursor = LoadCursor(nullptr, IDC_ARROW);; + windowClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); + windowClass.lpszMenuName = 0; + windowClass.lpszClassName = m_className.c_str(); + windowClass.hIconSm = smallIcon; + ATOM registeredClass{ RegisterClassExA(&windowClass) }; + if (registeredClass == 0) + { + throw std::runtime_error("Unable to register window class: " + std::to_string(GetLastError()) + "."); + } + m_hwnd = CreateWindowExA(0, m_className.c_str(), "AuraNotifyIcon", WS_CHILD, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, hwnd, nullptr, nullptr, nullptr); + if (!m_hwnd) + { + throw std::runtime_error("Unable to create window: " + std::to_string(GetLastError()) + "."); + } + m_icons.insert({ m_hwnd, this }); + //Create the NotifyIcon + if (CoCreateGuid(&m_guid) != S_OK) + { + throw std::runtime_error("Unable to create guid: " + std::to_string(GetLastError()) + "."); + } + NOTIFYICONDATAA notify{ getBaseNotifyIconData() }; + notify.uFlags |= NIF_ICON | NIF_TIP; + notify.hIcon = icon; + StringCchCopyA(notify.szTip, ARRAYSIZE(notify.szTip), m_tooltip.c_str()); + notify.uVersion = NOTIFYICON_VERSION_4; + if (!Shell_NotifyIconA(NIM_ADD, ¬ify)) + { + throw std::runtime_error("Unable to create NotifyIcon: " + std::to_string(GetLastError()) + "."); + } + Shell_NotifyIconA(NIM_SETVERSION, ¬ify); + //Create context menu + if (!m_contextMenu.empty()) + { + m_hmenu = CreatePopupMenu(); + if (!m_hmenu) + { + throw std::runtime_error("Unable to create menu: " + std::to_string(GetLastError()) + "."); + } + for (size_t i = 0; i < m_contextMenu.size(); i++) + { + const std::shared_ptr& item{ m_contextMenu.get(i) }; + if (item->getType() == NotifyIconMenuItemType::Action) + { + const NotifyIconActionMenuItem* action{ static_cast(item.get()) }; + MENUITEMINFOA actionItem{ 0 }; + actionItem.cbSize = sizeof(actionItem); + actionItem.fMask = MIIM_ID | MIIM_FTYPE | MIIM_STRING; + actionItem.fType = MFT_STRING; + actionItem.wID = static_cast(IDM_CONTEXT_MENU + i); + actionItem.dwTypeData = LPSTR(action->getLabel().c_str()); + actionItem.cch = static_cast(action->getLabel().size()); + InsertMenuItemA(m_hmenu, static_cast(i), TRUE, &actionItem); + } + else if (item->getType() == NotifyIconMenuItemType::Separator) + { + MENUITEMINFOA separatorItem{ 0 }; + separatorItem.cbSize = sizeof(separatorItem); + separatorItem.fMask = MIIM_ID | MIIM_FTYPE; + separatorItem.fType = MFT_SEPARATOR; + separatorItem.wID = static_cast(IDM_CONTEXT_MENU + i); + InsertMenuItemA(m_hmenu, static_cast(i), TRUE, &separatorItem); + } + } + } + } - NotifyIcon::~NotifyIcon() - { - //Destroy NotifyIcon - NOTIFYICONDATAA notify{ getBaseNotifyIconData() }; - Shell_NotifyIconA(NIM_DELETE, ¬ify); - //Destroy window for NotifyIcon - if (m_hmenu) - { - DestroyMenu(m_hmenu); - } - m_icons.erase(m_hwnd); - DestroyWindow(m_hwnd); - UnregisterClassA(m_className.c_str(), nullptr); - } + NotifyIcon::~NotifyIcon() + { + //Destroy NotifyIcon + NOTIFYICONDATAA notify{ getBaseNotifyIconData() }; + Shell_NotifyIconA(NIM_DELETE, ¬ify); + //Destroy window for NotifyIcon + if (m_hmenu) + { + DestroyMenu(m_hmenu); + } + m_icons.erase(m_hwnd); + DestroyWindow(m_hwnd); + UnregisterClassA(m_className.c_str(), nullptr); + } - bool NotifyIcon::hide() - { - m_isHidden = true; - NOTIFYICONDATAA notify{ getBaseNotifyIconData() }; - return Shell_NotifyIconA(NIM_MODIFY, ¬ify) == TRUE; - } + bool NotifyIcon::hide() + { + m_isHidden = true; + NOTIFYICONDATAA notify{ getBaseNotifyIconData() }; + return Shell_NotifyIconA(NIM_MODIFY, ¬ify) == TRUE; + } - bool NotifyIcon::show() - { - m_isHidden = false; - NOTIFYICONDATAA notify{ getBaseNotifyIconData() }; - return Shell_NotifyIconA(NIM_MODIFY, ¬ify) == TRUE; - } + bool NotifyIcon::show() + { + m_isHidden = false; + NOTIFYICONDATAA notify{ getBaseNotifyIconData() }; + return Shell_NotifyIconA(NIM_MODIFY, ¬ify) == TRUE; + } - const std::string& NotifyIcon::getTooltip() const - { - return m_tooltip; - } + const std::string& NotifyIcon::getTooltip() const + { + return m_tooltip; + } - bool NotifyIcon::setTooltip(const std::string& tooltip) - { - m_tooltip = tooltip; - NOTIFYICONDATAA notify{ getBaseNotifyIconData() }; - notify.uFlags |= NIF_TIP; - StringCchCopyA(notify.szTip, ARRAYSIZE(notify.szTip), m_tooltip.c_str()); - return Shell_NotifyIconA(NIM_MODIFY, ¬ify) == TRUE; - } + bool NotifyIcon::setTooltip(const std::string& tooltip) + { + m_tooltip = tooltip; + NOTIFYICONDATAA notify{ getBaseNotifyIconData() }; + notify.uFlags |= NIF_TIP; + StringCchCopyA(notify.szTip, ARRAYSIZE(notify.szTip), m_tooltip.c_str()); + return Shell_NotifyIconA(NIM_MODIFY, ¬ify) == TRUE; + } - bool NotifyIcon::notify(const ShellNotificationSentEventArgs& e) - { - NOTIFYICONDATAA notify{ getBaseNotifyIconData() }; - notify.uFlags |= NIF_INFO; - StringCchCopyA(notify.szInfo, ARRAYSIZE(notify.szInfo), e.getMessage().c_str()); - StringCchCopyA(notify.szInfoTitle, ARRAYSIZE(notify.szInfoTitle), e.getTitle().c_str()); - notify.dwInfoFlags = NIIF_RESPECT_QUIET_TIME; - if (e.getSeverity() == NotificationSeverity::Warning) - { - notify.dwInfoFlags |= NIIF_WARNING; - } - else if(e.getSeverity() == NotificationSeverity::Error) - { - notify.dwInfoFlags |= NIIF_ERROR; - } - else - { - notify.dwInfoFlags |= NIIF_NONE; - } - if (e.getAction() == "open" && std::filesystem::exists(e.getActionParam())) - { - m_openPath = e.getActionParam(); - } - else - { - m_openPath = std::filesystem::path(); - } - return Shell_NotifyIconA(NIM_MODIFY, ¬ify) == TRUE; - } + bool NotifyIcon::notify(const ShellNotificationSentEventArgs& e) + { + NOTIFYICONDATAA notify{ getBaseNotifyIconData() }; + notify.uFlags |= NIF_INFO; + StringCchCopyA(notify.szInfo, ARRAYSIZE(notify.szInfo), e.getMessage().c_str()); + StringCchCopyA(notify.szInfoTitle, ARRAYSIZE(notify.szInfoTitle), e.getTitle().c_str()); + notify.dwInfoFlags = NIIF_RESPECT_QUIET_TIME; + if (e.getSeverity() == NotificationSeverity::Warning) + { + notify.dwInfoFlags |= NIIF_WARNING; + } + else if(e.getSeverity() == NotificationSeverity::Error) + { + notify.dwInfoFlags |= NIIF_ERROR; + } + else + { + notify.dwInfoFlags |= NIIF_NONE; + } + if (e.getAction() == "open" && std::filesystem::exists(e.getActionParam())) + { + m_openPath = e.getActionParam(); + } + else + { + m_openPath = std::filesystem::path(); + } + return Shell_NotifyIconA(NIM_MODIFY, ¬ify) == TRUE; + } - NOTIFYICONDATAA NotifyIcon::getBaseNotifyIconData() - { - NOTIFYICONDATAA notify{ 0 }; - notify.cbSize = sizeof(notify); - notify.hWnd = m_hwnd; - notify.guidItem = m_guid; - notify.uFlags = NIF_MESSAGE | NIF_GUID | NIF_SHOWTIP; - if (m_isHidden) - { - notify.uFlags |= NIF_STATE; - notify.dwState = NIS_HIDDEN; - } - else - { - notify.uFlags |= NIF_STATE; - notify.dwState = 0; - } - notify.uCallbackMessage = WM_NOTIFYICON_EVENT; - return notify; - } + NOTIFYICONDATAA NotifyIcon::getBaseNotifyIconData() + { + NOTIFYICONDATAA notify{ 0 }; + notify.cbSize = sizeof(notify); + notify.hWnd = m_hwnd; + notify.guidItem = m_guid; + notify.uFlags = NIF_MESSAGE | NIF_GUID | NIF_SHOWTIP; + if (m_isHidden) + { + notify.uFlags |= NIF_STATE; + notify.dwState = NIS_HIDDEN; + } + else + { + notify.uFlags |= NIF_STATE; + notify.dwState = 0; + } + notify.uCallbackMessage = WM_NOTIFYICON_EVENT; + return notify; + } - LRESULT NotifyIcon::handleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam) - { - if (uMsg == WM_NOTIFYICON_EVENT) - { - if (LOWORD(lParam) == NIN_SELECT || LOWORD(lParam) == WM_CONTEXTMENU) - { - POINT point{ LOWORD(wParam), HIWORD(wParam) }; - SetForegroundWindow(m_hwnd); - UINT flags{ TPM_RIGHTBUTTON }; - if (GetSystemMetrics(SM_MENUDROPALIGNMENT) != 0) - { - flags |= TPM_RIGHTALIGN; - } - else - { - flags |= TPM_LEFTALIGN; - } - TrackPopupMenuEx(m_hmenu, flags, point.x, point.y, m_hwnd, nullptr); - return 0; - } - else if (LOWORD(lParam) == NIN_BALLOONUSERCLICK) - { - if (!m_openPath.empty() && std::filesystem::exists(m_openPath)) - { - ShellExecuteA(nullptr, "open", m_openPath.string().c_str(), nullptr, nullptr, SW_SHOWDEFAULT); - } - } - NOTIFYICONDATAA notify{ getBaseNotifyIconData() }; - Shell_NotifyIconA(NIM_MODIFY, ¬ify); - return 0; - } - else if (uMsg == WM_COMMAND) - { - int index{ LOWORD(wParam) - IDM_CONTEXT_MENU }; - if (m_contextMenu.size() != 0 && index >= 0 && index < m_contextMenu.size()) - { - const std::shared_ptr item{ m_contextMenu.get(index) }; - if (item->getType() == NotifyIconMenuItemType::Action) - { - const NotifyIconActionMenuItem* action{ static_cast(item.get()) }; - action->invoke(); - } - return 0; - } - } - return DefWindowProcA(m_hwnd, uMsg, wParam, lParam); - } + LRESULT NotifyIcon::handleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam) + { + if (uMsg == WM_NOTIFYICON_EVENT) + { + if (LOWORD(lParam) == NIN_SELECT || LOWORD(lParam) == WM_CONTEXTMENU) + { + POINT point{ LOWORD(wParam), HIWORD(wParam) }; + SetForegroundWindow(m_hwnd); + UINT flags{ TPM_RIGHTBUTTON }; + if (GetSystemMetrics(SM_MENUDROPALIGNMENT) != 0) + { + flags |= TPM_RIGHTALIGN; + } + else + { + flags |= TPM_LEFTALIGN; + } + TrackPopupMenuEx(m_hmenu, flags, point.x, point.y, m_hwnd, nullptr); + return 0; + } + else if (LOWORD(lParam) == NIN_BALLOONUSERCLICK) + { + if (!m_openPath.empty() && std::filesystem::exists(m_openPath)) + { + ShellExecuteA(nullptr, "open", m_openPath.string().c_str(), nullptr, nullptr, SW_SHOWDEFAULT); + } + } + NOTIFYICONDATAA notify{ getBaseNotifyIconData() }; + Shell_NotifyIconA(NIM_MODIFY, ¬ify); + return 0; + } + else if (uMsg == WM_COMMAND) + { + int index{ LOWORD(wParam) - IDM_CONTEXT_MENU }; + if (m_contextMenu.size() != 0 && index >= 0 && index < m_contextMenu.size()) + { + const std::shared_ptr item{ m_contextMenu.get(index) }; + if (item->getType() == NotifyIconMenuItemType::Action) + { + const NotifyIconActionMenuItem* action{ static_cast(item.get()) }; + action->invoke(); + } + return 0; + } + } + return DefWindowProcA(m_hwnd, uMsg, wParam, lParam); + } - LRESULT NotifyIcon::notifyIconWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) - { - if (m_icons.contains(hwnd)) - { - return m_icons[hwnd]->handleMessage(uMsg, wParam, lParam); - } - return DefWindowProcA(hwnd, uMsg, wParam, lParam); - } + LRESULT NotifyIcon::notifyIconWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) + { + if (m_icons.contains(hwnd)) + { + return m_icons[hwnd]->handleMessage(uMsg, wParam, lParam); + } + return DefWindowProcA(hwnd, uMsg, wParam, lParam); + } } #endif \ No newline at end of file diff --git a/src/notifications/notifyiconmenu.cpp b/src/notifications/notifyiconmenu.cpp index 2f6ff4f..625802c 100644 --- a/src/notifications/notifyiconmenu.cpp +++ b/src/notifications/notifyiconmenu.cpp @@ -3,130 +3,130 @@ namespace Nickvision::Notifications { - NotifyIconMenuItem::NotifyIconMenuItem(NotifyIconMenuItemType type) - : m_type{ type } - { - - } - - NotifyIconMenuItemType NotifyIconMenuItem::getType() const - { - return m_type; - } - - NotifyIconSeparatorMenuItem::NotifyIconSeparatorMenuItem() - : NotifyIconMenuItem{ NotifyIconMenuItemType::Separator } - { - - } - - NotifyIconActionMenuItem::NotifyIconActionMenuItem(const std::string& label, const std::function& action) - : NotifyIconMenuItem{ NotifyIconMenuItemType::Action }, - m_label{ label }, - m_action{ action } - { - - } - - const std::string& NotifyIconActionMenuItem::getLabel() const - { - return m_label; - } - - void NotifyIconActionMenuItem::invoke() const - { - if (m_action) - { - m_action(); - } - } - - void NotifyIconActionMenuItem::operator()() const - { - invoke(); - } - - size_t NotifyIconMenu::size() const - { - return m_items.size(); - } - - bool NotifyIconMenu::empty() const - { - return m_items.size() == 0; - } - - const std::shared_ptr& NotifyIconMenu::get(size_t index) const - { - if (index < 0 || index >= m_items.size()) - { - static std::shared_ptr null{ nullptr }; - return null; - } - return m_items[index]; - } - - size_t NotifyIconMenu::addSeparator() - { - m_items.push_back(std::make_shared()); - return m_items.size() - 1; - } - - bool NotifyIconMenu::insertSeparator(size_t index) - { - if (index < 0 || index > m_items.size()) - { - return false; - } - m_items.insert(m_items.begin() + index, std::make_shared()); - return true; - } - - bool NotifyIconMenu::removeSeparator(size_t index) - { - if (index < 0 || index >= m_items.size()) - { - return false; - } - const std::shared_ptr& item{ m_items[index] }; - if (item->getType() != NotifyIconMenuItemType::Separator) - { - return false; - } - m_items.erase(m_items.begin() + index); - return true; - } - - size_t NotifyIconMenu::addAction(const std::string& label, const std::function& action) - { - m_items.push_back(std::make_shared(label, action)); - return m_items.size() - 1; - } - - bool NotifyIconMenu::insertAction(size_t index, const std::string& label, const std::function& action) - { - if (index < 0 || index > m_items.size()) - { - return false; - } - m_items.insert(m_items.begin() + index, std::make_shared(label, action)); - return true; - } - - bool NotifyIconMenu::removeAction(size_t index) - { - if (index < 0 || index > m_items.size() - 1) - { - return false; - } - const std::shared_ptr& item{ m_items[index] }; - if (item->getType() != NotifyIconMenuItemType::Action) - { - return false; - } - m_items.erase(m_items.begin() + index); - return true; - } + NotifyIconMenuItem::NotifyIconMenuItem(NotifyIconMenuItemType type) + : m_type{ type } + { + + } + + NotifyIconMenuItemType NotifyIconMenuItem::getType() const + { + return m_type; + } + + NotifyIconSeparatorMenuItem::NotifyIconSeparatorMenuItem() + : NotifyIconMenuItem{ NotifyIconMenuItemType::Separator } + { + + } + + NotifyIconActionMenuItem::NotifyIconActionMenuItem(const std::string& label, const std::function& action) + : NotifyIconMenuItem{ NotifyIconMenuItemType::Action }, + m_label{ label }, + m_action{ action } + { + + } + + const std::string& NotifyIconActionMenuItem::getLabel() const + { + return m_label; + } + + void NotifyIconActionMenuItem::invoke() const + { + if (m_action) + { + m_action(); + } + } + + void NotifyIconActionMenuItem::operator()() const + { + invoke(); + } + + size_t NotifyIconMenu::size() const + { + return m_items.size(); + } + + bool NotifyIconMenu::empty() const + { + return m_items.size() == 0; + } + + const std::shared_ptr& NotifyIconMenu::get(size_t index) const + { + if (index < 0 || index >= m_items.size()) + { + static std::shared_ptr null{ nullptr }; + return null; + } + return m_items[index]; + } + + size_t NotifyIconMenu::addSeparator() + { + m_items.push_back(std::make_shared()); + return m_items.size() - 1; + } + + bool NotifyIconMenu::insertSeparator(size_t index) + { + if (index < 0 || index > m_items.size()) + { + return false; + } + m_items.insert(m_items.begin() + index, std::make_shared()); + return true; + } + + bool NotifyIconMenu::removeSeparator(size_t index) + { + if (index < 0 || index >= m_items.size()) + { + return false; + } + const std::shared_ptr& item{ m_items[index] }; + if (item->getType() != NotifyIconMenuItemType::Separator) + { + return false; + } + m_items.erase(m_items.begin() + index); + return true; + } + + size_t NotifyIconMenu::addAction(const std::string& label, const std::function& action) + { + m_items.push_back(std::make_shared(label, action)); + return m_items.size() - 1; + } + + bool NotifyIconMenu::insertAction(size_t index, const std::string& label, const std::function& action) + { + if (index < 0 || index > m_items.size()) + { + return false; + } + m_items.insert(m_items.begin() + index, std::make_shared(label, action)); + return true; + } + + bool NotifyIconMenu::removeAction(size_t index) + { + if (index < 0 || index > m_items.size() - 1) + { + return false; + } + const std::shared_ptr& item{ m_items[index] }; + if (item->getType() != NotifyIconMenuItemType::Action) + { + return false; + } + m_items.erase(m_items.begin() + index); + return true; + } } #endif \ No newline at end of file diff --git a/src/notifications/shellnotification.cpp b/src/notifications/shellnotification.cpp index 0d573a4..cf8c721 100644 --- a/src/notifications/shellnotification.cpp +++ b/src/notifications/shellnotification.cpp @@ -15,58 +15,58 @@ using namespace Nickvision::App; namespace Nickvision::Notifications { #ifdef _WIN32 - void ShellNotification::send(const ShellNotificationSentEventArgs& e, HWND hwnd) - { - static std::shared_ptr notifyIcon{ std::make_shared(hwnd, NotifyIconMenu(), true) }; - notifyIcon->hide(); - notifyIcon->notify(e); - } + void ShellNotification::send(const ShellNotificationSentEventArgs& e, HWND hwnd) + { + static std::shared_ptr notifyIcon{ std::make_shared(hwnd, NotifyIconMenu(), true) }; + notifyIcon->hide(); + notifyIcon->notify(e); + } #elif defined(__linux__) - void ShellNotification::send(const ShellNotificationSentEventArgs& e, const std::string& openText) - { - if (g_application_get_default()) - { - GNotification* notification{ g_notification_new(e.getTitle().c_str()) }; - GIcon* icon{ nullptr }; - GFile* fileIcon{ nullptr }; - std::string appId{ Aura::getActive().getAppInfo().getId() }; - if (Aura::getActive().getEnvVar("SNAP").empty()) - { - std::string name{ appId + "-symbolic" }; - icon = g_themed_icon_new(name.c_str()); - } - else - { - std::string path{ Aura::getActive().getEnvVar("SNAP") + "/usr/share/icons/hicolor/symbolic/apps/" + appId + "-symbolic.svg"}; - fileIcon = g_file_new_for_path(path.c_str()); - icon = g_file_icon_new(fileIcon); - } - g_notification_set_body(notification, e.getMessage().c_str()); - g_notification_set_icon(notification, icon); - if (e.getSeverity() == NotificationSeverity::Success) - { - g_notification_set_priority(notification, G_NOTIFICATION_PRIORITY_HIGH); - } - else if (e.getSeverity() == NotificationSeverity::Warning || e.getSeverity() == NotificationSeverity::Error) - { - g_notification_set_priority(notification, G_NOTIFICATION_PRIORITY_URGENT); - } - else - { - g_notification_set_priority(notification, G_NOTIFICATION_PRIORITY_NORMAL); - } - if (e.getAction() == "open" && std::filesystem::exists(e.getActionParam())) - { - g_notification_add_button_with_target_value(notification, openText.c_str(), "app.open", g_variant_new_string(e.getActionParam().c_str())); - } - g_application_send_notification(g_application_get_default(), appId.c_str(), notification); - if (fileIcon) - { - g_object_unref(G_OBJECT(fileIcon)); - } - g_object_unref(G_OBJECT(icon)); - g_object_unref(G_OBJECT(notification)); - } - } + void ShellNotification::send(const ShellNotificationSentEventArgs& e, const std::string& openText) + { + if (g_application_get_default()) + { + GNotification* notification{ g_notification_new(e.getTitle().c_str()) }; + GIcon* icon{ nullptr }; + GFile* fileIcon{ nullptr }; + std::string appId{ Aura::getActive().getAppInfo().getId() }; + if (Aura::getActive().getEnvVar("SNAP").empty()) + { + std::string name{ appId + "-symbolic" }; + icon = g_themed_icon_new(name.c_str()); + } + else + { + std::string path{ Aura::getActive().getEnvVar("SNAP") + "/usr/share/icons/hicolor/symbolic/apps/" + appId + "-symbolic.svg"}; + fileIcon = g_file_new_for_path(path.c_str()); + icon = g_file_icon_new(fileIcon); + } + g_notification_set_body(notification, e.getMessage().c_str()); + g_notification_set_icon(notification, icon); + if (e.getSeverity() == NotificationSeverity::Success) + { + g_notification_set_priority(notification, G_NOTIFICATION_PRIORITY_HIGH); + } + else if (e.getSeverity() == NotificationSeverity::Warning || e.getSeverity() == NotificationSeverity::Error) + { + g_notification_set_priority(notification, G_NOTIFICATION_PRIORITY_URGENT); + } + else + { + g_notification_set_priority(notification, G_NOTIFICATION_PRIORITY_NORMAL); + } + if (e.getAction() == "open" && std::filesystem::exists(e.getActionParam())) + { + g_notification_add_button_with_target_value(notification, openText.c_str(), "app.open", g_variant_new_string(e.getActionParam().c_str())); + } + g_application_send_notification(g_application_get_default(), appId.c_str(), notification); + if (fileIcon) + { + g_object_unref(G_OBJECT(fileIcon)); + } + g_object_unref(G_OBJECT(icon)); + g_object_unref(G_OBJECT(notification)); + } + } #endif } \ No newline at end of file diff --git a/src/notifications/shellnotificationsenteventargs.cpp b/src/notifications/shellnotificationsenteventargs.cpp index fdd11ec..5ac5fa8 100644 --- a/src/notifications/shellnotificationsenteventargs.cpp +++ b/src/notifications/shellnotificationsenteventargs.cpp @@ -2,15 +2,15 @@ namespace Nickvision::Notifications { - ShellNotificationSentEventArgs::ShellNotificationSentEventArgs(const std::string& title, const std::string& message, NotificationSeverity severity, const std::string& action, const std::string& actionParam) - : NotificationSentEventArgs{ message, severity, action, actionParam }, - m_title{ title } - { + ShellNotificationSentEventArgs::ShellNotificationSentEventArgs(const std::string& title, const std::string& message, NotificationSeverity severity, const std::string& action, const std::string& actionParam) + : NotificationSentEventArgs{ message, severity, action, actionParam }, + m_title{ title } + { - } + } - const std::string& ShellNotificationSentEventArgs::getTitle() const - { - return m_title; - } + const std::string& ShellNotificationSentEventArgs::getTitle() const + { + return m_title; + } } \ No newline at end of file diff --git a/src/update/version.cpp b/src/update/version.cpp index a2774f4..2325fa3 100644 --- a/src/update/version.cpp +++ b/src/update/version.cpp @@ -4,195 +4,195 @@ namespace Nickvision::Update { - Version::Version() - : m_major{ 0 }, - m_minor{ 0 }, - m_build{ 0 }, - m_str{ "0.0.0" } - { - - } - - Version::Version(int major, int minor, int build) - : m_major{ major }, - m_minor{ minor }, - m_build{ build }, - m_str{ std::to_string(major) + "." + std::to_string(minor) + "." + std::to_string(build) } - { - - } - - Version::Version(int major, int minor, int build, const std::string& dev) - : m_major{ major }, - m_minor{ minor }, - m_build{ build }, - m_dev{ dev }, - m_str{ std::to_string(major) + "." + std::to_string(minor) + "." + std::to_string(build) + dev } - { - if (m_dev[0] != '-') - { - throw std::invalid_argument("Dev version must contain a '-'."); - } - } - - Version::Version(const std::string& version) - : m_major{ 0 }, - m_minor{ 0 }, - m_build{ 0 } - { - std::string s{ version }; - size_t pos{ 0 }; - int i{ 0 }; - while ((pos = s.find('.')) != std::string::npos) - { - std::string token{ s.substr(0, pos) }; - if (i == 0) - { - m_major = std::stoi(token); - } - else if (i == 1) - { - m_minor = std::stoi(token); - } - else - { - throw std::invalid_argument("Ill-formated version string."); - } - s.erase(0, pos + 1); - i++; - } - if (i != 2) - { - throw std::invalid_argument("Ill-formated version string."); - } - size_t dashIndex{ s.find('-') }; - m_build = std::stoi(s.substr(0, dashIndex)); - s.erase(0, dashIndex); - if (!s.empty() && s[0] == '-') //dev version - { - m_dev = s; - } - m_str = std::to_string(m_major) + "." + std::to_string(m_minor) + "." + std::to_string(m_build) + m_dev; - } - - int Version::getMajor() const - { - return m_major; - } - - int Version::getMinor() const - { - return m_minor; - } - - int Version::getBuild() const - { - return m_build; - } - - const std::string& Version::getDev() const - { - return m_dev; - } - - VersionType Version::getVersionType() const - { - return m_dev.empty() ? VersionType::Stable : VersionType::Preview; - } - - const std::string& Version::toString() const - { - return m_str; - } - - bool Version::empty() const - { - return m_major == 0 && m_minor == 0 && m_build == 0 && m_dev.empty(); - } - - bool Version::operator<(const Version& compare) const - { - if (m_major < compare.m_major) - { - return true; - } - else - { - if (m_minor < compare.m_minor) - { - return true; - } - else - { - if (m_build < compare.m_build) - { - return true; - } - else - { - if (!m_dev.empty() && compare.m_dev.empty()) //dev < stable - { - return true; - } - } - } - } - return false; - } - - bool Version::operator<=(const Version& compare) const - { - return operator>(compare) || operator==(compare); - } - - bool Version::operator>(const Version& compare) const - { - if (m_major > compare.m_major) - { - return true; - } - else - { - if (m_minor > compare.m_minor) - { - return true; - } - else - { - if (m_build > compare.m_build) - { - return true; - } - else - { - if (m_dev.empty() && !compare.m_dev.empty()) //stable > dev - { - return true; - } - } - } - } - return false; - } - - bool Version::operator>=(const Version& compare) const - { - return operator<(compare) || operator==(compare); - } - - bool Version::operator==(const Version& compare) const - { - return m_major == compare.m_major && m_minor == compare.m_minor && m_build == compare.m_build && m_dev == compare.m_dev; - } - - bool Version::operator!=(const Version& compare) const - { - return !(operator==(compare)); - } - - std::ostream& operator<<(std::ostream& os, const Version& version) - { - os << version.toString(); - return os; - } + Version::Version() + : m_major{ 0 }, + m_minor{ 0 }, + m_build{ 0 }, + m_str{ "0.0.0" } + { + + } + + Version::Version(int major, int minor, int build) + : m_major{ major }, + m_minor{ minor }, + m_build{ build }, + m_str{ std::to_string(major) + "." + std::to_string(minor) + "." + std::to_string(build) } + { + + } + + Version::Version(int major, int minor, int build, const std::string& dev) + : m_major{ major }, + m_minor{ minor }, + m_build{ build }, + m_dev{ dev }, + m_str{ std::to_string(major) + "." + std::to_string(minor) + "." + std::to_string(build) + dev } + { + if (m_dev[0] != '-') + { + throw std::invalid_argument("Dev version must contain a '-'."); + } + } + + Version::Version(const std::string& version) + : m_major{ 0 }, + m_minor{ 0 }, + m_build{ 0 } + { + std::string s{ version }; + size_t pos{ 0 }; + int i{ 0 }; + while ((pos = s.find('.')) != std::string::npos) + { + std::string token{ s.substr(0, pos) }; + if (i == 0) + { + m_major = std::stoi(token); + } + else if (i == 1) + { + m_minor = std::stoi(token); + } + else + { + throw std::invalid_argument("Ill-formated version string."); + } + s.erase(0, pos + 1); + i++; + } + if (i != 2) + { + throw std::invalid_argument("Ill-formated version string."); + } + size_t dashIndex{ s.find('-') }; + m_build = std::stoi(s.substr(0, dashIndex)); + s.erase(0, dashIndex); + if (!s.empty() && s[0] == '-') //dev version + { + m_dev = s; + } + m_str = std::to_string(m_major) + "." + std::to_string(m_minor) + "." + std::to_string(m_build) + m_dev; + } + + int Version::getMajor() const + { + return m_major; + } + + int Version::getMinor() const + { + return m_minor; + } + + int Version::getBuild() const + { + return m_build; + } + + const std::string& Version::getDev() const + { + return m_dev; + } + + VersionType Version::getVersionType() const + { + return m_dev.empty() ? VersionType::Stable : VersionType::Preview; + } + + const std::string& Version::toString() const + { + return m_str; + } + + bool Version::empty() const + { + return m_major == 0 && m_minor == 0 && m_build == 0 && m_dev.empty(); + } + + bool Version::operator<(const Version& compare) const + { + if (m_major < compare.m_major) + { + return true; + } + else + { + if (m_minor < compare.m_minor) + { + return true; + } + else + { + if (m_build < compare.m_build) + { + return true; + } + else + { + if (!m_dev.empty() && compare.m_dev.empty()) //dev < stable + { + return true; + } + } + } + } + return false; + } + + bool Version::operator<=(const Version& compare) const + { + return operator>(compare) || operator==(compare); + } + + bool Version::operator>(const Version& compare) const + { + if (m_major > compare.m_major) + { + return true; + } + else + { + if (m_minor > compare.m_minor) + { + return true; + } + else + { + if (m_build > compare.m_build) + { + return true; + } + else + { + if (m_dev.empty() && !compare.m_dev.empty()) //stable > dev + { + return true; + } + } + } + } + return false; + } + + bool Version::operator>=(const Version& compare) const + { + return operator<(compare) || operator==(compare); + } + + bool Version::operator==(const Version& compare) const + { + return m_major == compare.m_major && m_minor == compare.m_minor && m_build == compare.m_build && m_dev == compare.m_dev; + } + + bool Version::operator!=(const Version& compare) const + { + return !(operator==(compare)); + } + + std::ostream& operator<<(std::ostream& os, const Version& version) + { + os << version.toString(); + return os; + } } \ No newline at end of file From 1d7af731098b8cf6c7b498e9016764c73562b14f Mon Sep 17 00:00:00 2001 From: Nick Logozzo Date: Mon, 29 Jan 2024 20:19:00 -0500 Subject: [PATCH 06/10] Taskbar - Fix Windows Count Displaying Wrong Fixes #19 --- src/taskbar/taskbaritem.cpp | 379 ++++++++++++++++++------------------ 1 file changed, 188 insertions(+), 191 deletions(-) diff --git a/src/taskbar/taskbaritem.cpp b/src/taskbar/taskbaritem.cpp index a93c9bd..dc808fb 100644 --- a/src/taskbar/taskbaritem.cpp +++ b/src/taskbar/taskbaritem.cpp @@ -9,237 +9,234 @@ using namespace Gdiplus; namespace Nickvision::Taskbar { - TaskbarItem::TaskbarItem() - : m_progressState{ ProgressState::NoProgress }, - m_progress{ 0.0 }, - m_urgent{ false }, - m_countVisible{ false }, - m_count{ 0 } - { + TaskbarItem::TaskbarItem() + : m_progressState{ ProgressState::NoProgress }, + m_progress{ 0.0 }, + m_urgent{ false }, + m_countVisible{ false }, + m_count{ 0 } + { #ifdef _WIN32 - GdiplusStartupInput gdiStartupIn; - GdiplusStartupOutput gdiStartupOut; - CoInitializeEx(nullptr, COINIT_MULTITHREADED); - GdiplusStartup(&m_gdi, &gdiStartupIn, &gdiStartupOut); - m_hwnd = nullptr; - m_taskbar = nullptr; + GdiplusStartupInput gdiStartupIn; + GdiplusStartupOutput gdiStartupOut; + CoInitializeEx(nullptr, COINIT_MULTITHREADED); + GdiplusStartup(&m_gdi, &gdiStartupIn, &gdiStartupOut); + m_hwnd = nullptr; + m_taskbar = nullptr; #elif defined(__linux__) - m_connection = nullptr; - m_objectPath = ""; - m_appUri = ""; + m_connection = nullptr; + m_objectPath = ""; + m_appUri = ""; #endif - } + } - TaskbarItem::~TaskbarItem() - { - setProgressState(ProgressState::NoProgress); - setUrgent(false); - setCountVisible(false); + TaskbarItem::~TaskbarItem() + { + setProgressState(ProgressState::NoProgress); + setUrgent(false); + setCountVisible(false); #ifdef _WIN32 - GdiplusShutdown(m_gdi); + GdiplusShutdown(m_gdi); #endif - } + } - ProgressState TaskbarItem::getProgressState() const - { - std::lock_guard lock{ m_mutex }; - return m_progressState; - } + ProgressState TaskbarItem::getProgressState() const + { + std::lock_guard lock{ m_mutex }; + return m_progressState; + } - void TaskbarItem::setProgressState(ProgressState state) - { - std::lock_guard lock{ m_mutex }; - m_progressState = state; + void TaskbarItem::setProgressState(ProgressState state) + { + std::lock_guard lock{ m_mutex }; + m_progressState = state; #ifdef _WIN32 - if (m_taskbar) - { - m_taskbar->SetProgressState(m_hwnd, (TBPFLAG)m_progressState); - } + if (m_taskbar) + { + m_taskbar->SetProgressState(m_hwnd, (TBPFLAG)m_progressState); + } #elif defined(__linux__) - if (m_connection) - { - sendDBusUpdate(); - } + sendDBusUpdate(); #endif - } + } - double TaskbarItem::getProgress() const - { - std::lock_guard lock{ m_mutex }; - return m_progress; - } + double TaskbarItem::getProgress() const + { + std::lock_guard lock{ m_mutex }; + return m_progress; + } - void TaskbarItem::setProgress(double progress) - { - setProgressState(progress == 0 ? ProgressState::NoProgress : ProgressState::Normal); - std::lock_guard lock{ m_mutex }; - m_progress = progress; + void TaskbarItem::setProgress(double progress) + { + setProgressState(progress == 0 ? ProgressState::NoProgress : ProgressState::Normal); + std::lock_guard lock{ m_mutex }; + m_progress = progress; #ifdef _WIN32 - if (m_taskbar) - { - m_taskbar->SetProgressValue(m_hwnd, static_cast(m_progress * 100), 100u); - } + if (m_taskbar) + { + m_taskbar->SetProgressValue(m_hwnd, static_cast(m_progress * 100), 100u); + } #elif defined(__linux__) - if (m_connection) - { - sendDBusUpdate(); - } + sendDBusUpdate(); #endif - } + } - bool TaskbarItem::getUrgent() const - { - std::lock_guard lock{ m_mutex }; - return m_urgent; - } + bool TaskbarItem::getUrgent() const + { + std::lock_guard lock{ m_mutex }; + return m_urgent; + } - void TaskbarItem::setUrgent(bool urgent) - { - std::lock_guard lock{ m_mutex }; - m_urgent = urgent; + void TaskbarItem::setUrgent(bool urgent) + { + std::lock_guard lock{ m_mutex }; + m_urgent = urgent; #ifdef _WIN32 - if (m_taskbar) - { - FLASHWINFO flashInfo; - flashInfo.cbSize = sizeof(FLASHWINFO); - flashInfo.hwnd = m_hwnd; - flashInfo.dwFlags = m_urgent ? (FLASHW_TRAY | FLASHW_TIMER) : FLASHW_STOP; - flashInfo.uCount = (std::numeric_limits::max)(); - flashInfo.dwTimeout = 0; - FlashWindowEx(&flashInfo); - } + if (m_taskbar) + { + FLASHWINFO flashInfo; + flashInfo.cbSize = sizeof(FLASHWINFO); + flashInfo.hwnd = m_hwnd; + flashInfo.dwFlags = m_urgent ? (FLASHW_TRAY | FLASHW_TIMER) : FLASHW_STOP; + flashInfo.uCount = (std::numeric_limits::max)(); + flashInfo.dwTimeout = 0; + FlashWindowEx(&flashInfo); + } #elif defined(__linux__) - if (m_connection) - { - sendDBusUpdate(); - } + sendDBusUpdate(); #endif - } + } - bool TaskbarItem::getCountVisible() const - { - std::lock_guard lock{ m_mutex }; - return m_countVisible; - } + bool TaskbarItem::getCountVisible() const + { + std::lock_guard lock{ m_mutex }; + return m_countVisible; + } - void TaskbarItem::setCountVisible(bool countVisible) - { - std::lock_guard lock{ m_mutex }; - m_countVisible = countVisible; + void TaskbarItem::setCountVisible(bool countVisible) + { + std::lock_guard lock{ m_mutex }; + m_countVisible = countVisible; #ifdef _WIN32 - if (m_taskbar) - { - if (!m_countVisible) - { - m_taskbar->SetOverlayIcon(m_hwnd, nullptr, L""); - } - else - { - DWORD accentColor; - BOOL opaue{ FALSE }; - Graphics windowGraphics{ m_hwnd }; - SolidBrush background{ DwmGetColorizationColor(&accentColor, &opaue) == S_OK ? Color::Color(accentColor) : Color::Color(0, 0, 0) }; - SolidBrush foreground{ Color::Color(255, 255, 255) }; - Bitmap bitmap{ 16, 16, &windowGraphics }; - Graphics graphics{ &bitmap }; - FontFamily fontFamily{ L"Microsoft Sans Serif" }; - Font font{ &fontFamily, m_count <= 99 ? (m_count < 10 ? 9.0f : 7.5f) : 7.0f }; - std::wstring countStr{ m_count > 99 ? L"99+" : std::to_wstring(m_count) }; - SizeF stringSize; - graphics.MeasureString(countStr.c_str(), (int)countStr.length(), &font, SizeF(16, 16), StringFormat::GenericDefault(), &stringSize); - graphics.FillEllipse(&background, Rect(0, 0, 16, 16)); - graphics.DrawString(countStr.c_str(), (int)countStr.length(), &font, PointF((16 - stringSize.Width) / 2, (16 - stringSize.Height) / 2), &foreground); - HICON icon{ nullptr }; - bitmap.GetHICON(&icon); - m_taskbar->SetOverlayIcon(m_hwnd, icon, std::to_wstring(m_count).c_str()); - DestroyIcon(icon); - } - } + if (m_taskbar) + { + if (!m_countVisible) + { + m_taskbar->SetOverlayIcon(m_hwnd, nullptr, L""); + } + else + { + drawCountIcon(); + } + } #elif defined(__linux__) - if (m_connection) - { - sendDBusUpdate(); - } + sendDBusUpdate(); #endif - } + } - long TaskbarItem::getCount() const - { - std::lock_guard lock{ m_mutex }; - return m_count; - } + long TaskbarItem::getCount() const + { + std::lock_guard lock{ m_mutex }; + return m_count; + } - void TaskbarItem::setCount(long count) - { - setCountVisible(count > 0); - std::lock_guard lock{ m_mutex }; - m_count = count; -#ifdef __linux__ - if (m_connection) - { - sendDBusUpdate(); - } + void TaskbarItem::setCount(long count) + { + setCountVisible(count > 0); + std::lock_guard lock{ m_mutex }; + m_count = count; +#ifdef _WIN32 + drawCountIcon(); +#elif defined(__linux__) + sendDBusUpdate(); #endif - } + } #ifdef _WIN32 - bool TaskbarItem::connect(HWND hwnd) - { + bool TaskbarItem::connect(HWND hwnd) + { if(m_hwnd) { return true; } - std::lock_guard lock{ m_mutex }; - if (!hwnd) - { - return false; - } - if (CoCreateInstance(CLSID_TaskbarList, nullptr, CLSCTX_ALL, __uuidof(ITaskbarList3), (LPVOID*)&m_taskbar) == S_OK) - { - m_hwnd = hwnd; - return m_taskbar->HrInit() == S_OK; - } - return false; - } + std::lock_guard lock{ m_mutex }; + if (!hwnd) + { + return false; + } + if (CoCreateInstance(CLSID_TaskbarList, nullptr, CLSCTX_ALL, __uuidof(ITaskbarList3), (LPVOID*)&m_taskbar) == S_OK) + { + m_hwnd = hwnd; + return m_taskbar->HrInit() == S_OK; + } + return false; + } + + void TaskbarItem::drawCountIcon() + { + DWORD accentColor; + Graphics windowGraphics{ m_hwnd }; + SolidBrush background{ DwmGetColorizationColor(&accentColor, nullptr) == S_OK ? Color::Color(accentColor) : Color::Color(0, 0, 0) }; + SolidBrush foreground{ Color::Color(255, 255, 255) }; + Color backgroundColor; + background.GetColor(&backgroundColor); + background.SetColor({ 255, backgroundColor.GetR(), backgroundColor.GetG(), backgroundColor.GetB() }); + Bitmap bitmap{ 16, 16, &windowGraphics }; + Graphics graphics{ &bitmap }; + FontFamily fontFamily{ L"Microsoft Sans Serif" }; + Font font{ &fontFamily, m_count <= 99 ? (m_count < 10 ? 8.0f : 7.5f) : 7.0f }; + std::wstring countStr{ m_count > 99 ? L"99+" : std::to_wstring(m_count) }; + SizeF stringSize; + graphics.MeasureString(countStr.c_str(), (int)countStr.length(), &font, SizeF(16, 16), StringFormat::GenericDefault(), &stringSize); + graphics.FillEllipse(&background, Rect(0, 0, 16, 16)); + graphics.DrawString(countStr.c_str(), (int)countStr.length(), &font, PointF((16 - stringSize.Width) / 2, (16 - stringSize.Height) / 2), &foreground); + HICON icon{ nullptr }; + bitmap.GetHICON(&icon); + m_taskbar->SetOverlayIcon(m_hwnd, icon, std::to_wstring(m_count).c_str()); + DestroyIcon(icon); + } #elif defined(__linux__) - bool TaskbarItem::connect(const std::string& desktopFile) - { + bool TaskbarItem::connect(const std::string& desktopFile) + { if(m_connection) { return true; } - std::lock_guard lock{ m_mutex }; - if (desktopFile.empty()) - { - return false; - } - m_connection = g_bus_get_sync(G_BUS_TYPE_SESSION, nullptr, nullptr); //returns a singleton, no need to manage it - if (m_connection) - { - unsigned long hash{ 5381 }; - for(char c : desktopFile) - { - hash = (hash << 5) + hash + c; - } - m_objectPath = "/com/canonical/unity/launcherentry/" + std::to_string(hash); - m_appUri = "application://" + desktopFile; - return true; - } - return false; - } + std::lock_guard lock{ m_mutex }; + if (desktopFile.empty()) + { + return false; + } + m_connection = g_bus_get_sync(G_BUS_TYPE_SESSION, nullptr, nullptr); //returns a singleton, no need to manage it + if (m_connection) + { + unsigned long hash{ 5381 }; + for(char c : desktopFile) + { + hash = (hash << 5) + hash + c; + } + m_objectPath = "/com/canonical/unity/launcherentry/" + std::to_string(hash); + m_appUri = "application://" + desktopFile; + return true; + } + return false; + } - void TaskbarItem::sendDBusUpdate() - { - GVariantBuilder builder; - g_variant_builder_init(&builder, G_VARIANT_TYPE("a{sv}")); - g_variant_builder_add(&builder, "{sv}", "progress-visible", g_variant_new_boolean(m_progressState >= ProgressState::Normal)); - g_variant_builder_add(&builder, "{sv}", "progress", g_variant_new_double(m_progress)); - g_variant_builder_add(&builder, "{sv}", "urgent", g_variant_new_boolean(m_urgent)); - g_variant_builder_add(&builder, "{sv}", "count-visible", g_variant_new_boolean(m_countVisible)); - g_variant_builder_add(&builder, "{sv}", "count", g_variant_new_int64(m_count)); - GVariant* params[2]{ g_variant_new_string(m_appUri.c_str()), g_variant_builder_end(&builder) }; - GVariant* tuple{ g_variant_new_tuple(params, 2) }; - g_dbus_connection_emit_signal(m_connection, nullptr, m_objectPath.c_str(), "com.canonical.Unity.LauncherEntry", "Update", tuple, nullptr); - } + void TaskbarItem::sendDBusUpdate() + { + if(m_connection) + { + GVariantBuilder builder; + g_variant_builder_init(&builder, G_VARIANT_TYPE("a{sv}")); + g_variant_builder_add(&builder, "{sv}", "progress-visible", g_variant_new_boolean(m_progressState >= ProgressState::Normal)); + g_variant_builder_add(&builder, "{sv}", "progress", g_variant_new_double(m_progress)); + g_variant_builder_add(&builder, "{sv}", "urgent", g_variant_new_boolean(m_urgent)); + g_variant_builder_add(&builder, "{sv}", "count-visible", g_variant_new_boolean(m_countVisible)); + g_variant_builder_add(&builder, "{sv}", "count", g_variant_new_int64(m_count)); + GVariant* params[2]{ g_variant_new_string(m_appUri.c_str()), g_variant_builder_end(&builder) }; + GVariant* tuple{ g_variant_new_tuple(params, 2) }; + g_dbus_connection_emit_signal(m_connection, nullptr, m_objectPath.c_str(), "com.canonical.Unity.LauncherEntry", "Update", tuple, nullptr); + } + } #endif } \ No newline at end of file From 7561faac62133f4288854d369a4b1a37410c9956 Mon Sep 17 00:00:00 2001 From: Nick Logozzo Date: Mon, 29 Jan 2024 22:06:11 -0500 Subject: [PATCH 07/10] App - Add Runtime Info APIs Fixes #18 --- docs/app.md | 20 +++++++++++++++ include/app/aura.h | 27 +++++++++++++++++++- src/app/aura.cpp | 37 +++++++++++++++++++++++++--- src/filesystem/filesystemwatcher.cpp | 2 +- src/filesystem/userdirectories.cpp | 2 +- src/taskbar/taskbaritem.cpp | 3 +-- tests/auratests.cpp | 11 +++++++++ 7 files changed, 94 insertions(+), 8 deletions(-) diff --git a/docs/app.md b/docs/app.md index e3cfec1..f1558c9 100644 --- a/docs/app.md +++ b/docs/app.md @@ -142,6 +142,26 @@ Path: `Nickvision::App::Aura` std::filesystem::path& ExecutableDirectory: get ``` - The path of the executable's directory. +- ``` + bool IsRunningOnWindows: get + ``` + - Whether or not the app is running on Windows +- ``` + bool IsRunningOnLinux: get + ``` + - Whether or not the app is running on Linux +- ``` + bool IsRunningViaFlatpak: get + ``` + - Whether or not the app is running via Flatpak +- ``` + bool IsRunningViaSnap: get + ``` + - Whether or not the app is running via Snap +- ``` + bool IsRunningViaLocal: get + ``` + - Whether or not the app is running locally ### Methods - ```cpp diff --git a/include/app/aura.h b/include/app/aura.h index 68a630c..1bcff71 100644 --- a/include/app/aura.h +++ b/include/app/aura.h @@ -50,6 +50,31 @@ namespace Nickvision::App * @return The executable's directory path */ const std::filesystem::path& getExecutableDirectory() const; + /** + * @brief Gets whether or not the app is running on Windows. + * @return True if running on Windows, else false + */ + bool isRunningOnWindows() const; + /** + * @brief Gets whether or not the app is running on Linux. + * @return True if running on Linux, else false + */ + bool isRunningOnLinux() const; + /** + * @brief Gets whether or not the app is running via Flatpak. + * @return True if running via Flatpak, else false + */ + bool isRunningViaFlatpak() const; + /** + * @brief Gets whether or not the app is running via Snap. + * @return True if running via Snap, else false + */ + bool isRunningViaSnap() const; + /** + * @brief Gets whether or not the app is running locally. + * @return True if running locally, else false + */ + bool isRunningViaLocal() const; /** * @brief Gets the AppInfo object for the application. */ @@ -64,7 +89,7 @@ namespace Nickvision::App * @param key The environment variable to get * @return The environment variable if found, else empty string */ - std::string getEnvVar(const std::string& key); + std::string getEnvVar(const std::string& key) const; /** * @brief Sets a system environment variable. * @param key The environment variable to set diff --git a/src/app/aura.cpp b/src/app/aura.cpp index 15d1ccf..521ac0b 100644 --- a/src/app/aura.cpp +++ b/src/app/aura.cpp @@ -6,8 +6,6 @@ #include "helpers/stringhelpers.h" #ifdef _WIN32 #include -#elif defined(__linux__) -#include #endif using namespace Nickvision::Filesystem; @@ -72,6 +70,39 @@ namespace Nickvision::App return m_executableDirectory; } + bool Aura::isRunningOnWindows() const + { +#ifdef _WIN32 + return true; +#else + return false; +#endif + } + + bool Aura::isRunningOnLinux() const + { +#ifdef __linux__ + return true; +#else + return false; +#endif + } + + bool Aura::isRunningViaFlatpak() const + { + return std::filesystem::exists("/.flatpak-info"); + } + + bool Aura::isRunningViaSnap() const + { + return !getEnvVar("SNAP").empty(); + } + + bool Aura::isRunningViaLocal() const + { + return !isRunningViaFlatpak() && !isRunningViaSnap(); + } + AppInfo& Aura::getAppInfo() { return m_appInfo; @@ -86,7 +117,7 @@ namespace Nickvision::App return *m_ipc; } - std::string Aura::getEnvVar(const std::string& key) + std::string Aura::getEnvVar(const std::string& key) const { char* var{ std::getenv(key.c_str()) }; if (var) diff --git a/src/filesystem/filesystemwatcher.cpp b/src/filesystem/filesystemwatcher.cpp index 18f822a..6e9ddd1 100644 --- a/src/filesystem/filesystemwatcher.cpp +++ b/src/filesystem/filesystemwatcher.cpp @@ -1,8 +1,8 @@ #include "filesystem/filesystemwatcher.h" +#include #include #include #ifdef __linux__ -#include #include #include #endif diff --git a/src/filesystem/userdirectories.cpp b/src/filesystem/userdirectories.cpp index 2cb29b6..93d9fd0 100644 --- a/src/filesystem/userdirectories.cpp +++ b/src/filesystem/userdirectories.cpp @@ -1,4 +1,5 @@ #include "filesystem/userdirectories.h" +#include #include #include #include "app/aura.h" @@ -6,7 +7,6 @@ #ifdef _WIN32 #include #elif defined(__linux__) -#include #include #include #include diff --git a/src/taskbar/taskbaritem.cpp b/src/taskbar/taskbaritem.cpp index dc808fb..d62071b 100644 --- a/src/taskbar/taskbaritem.cpp +++ b/src/taskbar/taskbaritem.cpp @@ -1,10 +1,9 @@ #include "taskbar/taskbaritem.h" +#include #include #ifdef _WIN32 #include using namespace Gdiplus; -#elif defined(__linux__) -#include #endif namespace Nickvision::Taskbar diff --git a/tests/auratests.cpp b/tests/auratests.cpp index 801f3e8..08645cf 100644 --- a/tests/auratests.cpp +++ b/tests/auratests.cpp @@ -97,4 +97,15 @@ TEST_F(AuraTest, DependencyCheck) #elif defined(__linux__) ASSERT_NO_THROW(ShellNotification::send(args, "Open")); #endif +} + +TEST_F(AuraTest, RunningInformationChecks) +{ + ASSERT_TRUE(!Aura::getActive().getExecutableDirectory().empty()); +#ifdef _WIN32 + ASSERT_TRUE(Aura::getActive().isRunningOnWindows()); +#elif defined(__linux__) + ASSERT_TRUE(Aura::getActive().isRunningOnLinux()); +#endif + ASSERT_TRUE(Aura::getActive().isRunningViaLocal()); } \ No newline at end of file From 58a125f9cfebc588a43a3d547b1700bbe9bef526 Mon Sep 17 00:00:00 2001 From: Nick Logozzo Date: Mon, 29 Jan 2024 22:27:50 -0500 Subject: [PATCH 08/10] GitHub Actions - Update vcpkg --- .github/workflows/linux.yml | 2 +- .github/workflows/windows.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 7e4963f..1695f3f 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -50,7 +50,7 @@ jobs: pkgs: boost-locale curl gettext-libintl glib gtest jsoncpp libsecret libuuid maddy openssl triplet: x64-linux cache-key: ${{ matrix.config.os }} - revision: 7032c5759f823fc8699a5c37d5f7072464ccb9a8 + revision: 4a2c30139309a6e4690ce929df33e85a1706a0e2 token: ${{ secrets.GITHUB_TOKEN }} - name: "Build" working-directory: ${{github.workspace}}/build diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index 1018e16..252623b 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -37,7 +37,7 @@ jobs: pkgs: boost-locale curl gettext-libintl gtest jsoncpp maddy openssl triplet: x64-windows cache-key: ${{ matrix.config.os }} - revision: 7032c5759f823fc8699a5c37d5f7072464ccb9a8 + revision: 4a2c30139309a6e4690ce929df33e85a1706a0e2 token: ${{ secrets.GITHUB_TOKEN }} - name: "Build" working-directory: ${{github.workspace}}/build From 2c010174a80424e947b615fe6821837492a87a88 Mon Sep 17 00:00:00 2001 From: Nick Logozzo Date: Mon, 29 Jan 2024 22:28:10 -0500 Subject: [PATCH 09/10] Taskbar - Code Cleanup --- src/taskbar/taskbaritem.cpp | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/taskbar/taskbaritem.cpp b/src/taskbar/taskbaritem.cpp index d62071b..7c89290 100644 --- a/src/taskbar/taskbaritem.cpp +++ b/src/taskbar/taskbaritem.cpp @@ -173,13 +173,16 @@ namespace Nickvision::Taskbar void TaskbarItem::drawCountIcon() { - DWORD accentColor; Graphics windowGraphics{ m_hwnd }; - SolidBrush background{ DwmGetColorizationColor(&accentColor, nullptr) == S_OK ? Color::Color(accentColor) : Color::Color(0, 0, 0) }; + SolidBrush background{ Color::Color(0, 0, 0) }; SolidBrush foreground{ Color::Color(255, 255, 255) }; - Color backgroundColor; - background.GetColor(&backgroundColor); - background.SetColor({ 255, backgroundColor.GetR(), backgroundColor.GetG(), backgroundColor.GetB() }); + DWORD accentARGB; + BOOL opaque{ FALSE }; + if(DwmGetColorizationColor(&accentARGB, &opaque) == S_OK) + { + Color accentColor{ accentARGB }; + background.SetColor({ 255, accentColor.GetR(), accentColor.GetG(), accentColor.GetB() }); + } Bitmap bitmap{ 16, 16, &windowGraphics }; Graphics graphics{ &bitmap }; FontFamily fontFamily{ L"Microsoft Sans Serif" }; From 9684767080a370468495392c86d3d5bdde858d46 Mon Sep 17 00:00:00 2001 From: Nick Logozzo Date: Mon, 29 Jan 2024 23:01:33 -0500 Subject: [PATCH 10/10] Update taskbaritem.cpp --- src/taskbar/taskbaritem.cpp | 44 +++++++++++++++++++------------------ 1 file changed, 23 insertions(+), 21 deletions(-) diff --git a/src/taskbar/taskbaritem.cpp b/src/taskbar/taskbaritem.cpp index 7c89290..df35dce 100644 --- a/src/taskbar/taskbaritem.cpp +++ b/src/taskbar/taskbaritem.cpp @@ -173,29 +173,31 @@ namespace Nickvision::Taskbar void TaskbarItem::drawCountIcon() { - Graphics windowGraphics{ m_hwnd }; - SolidBrush background{ Color::Color(0, 0, 0) }; - SolidBrush foreground{ Color::Color(255, 255, 255) }; - DWORD accentARGB; - BOOL opaque{ FALSE }; - if(DwmGetColorizationColor(&accentARGB, &opaque) == S_OK) + if (m_taskbar) { - Color accentColor{ accentARGB }; - background.SetColor({ 255, accentColor.GetR(), accentColor.GetG(), accentColor.GetB() }); + Graphics windowGraphics{ m_hwnd }; + SolidBrush background{ Color::Color(0, 0, 0) }; + SolidBrush foreground{ Color::Color(255, 255, 255) }; + DWORD accentARGB; + if(DwmGetColorizationColor(&accentARGB, nullptr) == S_OK) + { + Color accentColor{ accentARGB }; + background.SetColor({ 255, accentColor.GetR(), accentColor.GetG(), accentColor.GetB() }); + } + Bitmap bitmap{ 16, 16, &windowGraphics }; + Graphics graphics{ &bitmap }; + FontFamily fontFamily{ L"Microsoft Sans Serif" }; + Font font{ &fontFamily, m_count <= 99 ? (m_count < 10 ? 8.0f : 7.5f) : 7.0f }; + std::wstring countStr{ m_count > 99 ? L"99+" : std::to_wstring(m_count) }; + SizeF stringSize; + graphics.MeasureString(countStr.c_str(), (int)countStr.length(), &font, SizeF(16, 16), StringFormat::GenericDefault(), &stringSize); + graphics.FillEllipse(&background, Rect(0, 0, 16, 16)); + graphics.DrawString(countStr.c_str(), (int)countStr.length(), &font, PointF((16 - stringSize.Width) / 2, (16 - stringSize.Height) / 2), &foreground); + HICON icon{ nullptr }; + bitmap.GetHICON(&icon); + m_taskbar->SetOverlayIcon(m_hwnd, icon, std::to_wstring(m_count).c_str()); + DestroyIcon(icon); } - Bitmap bitmap{ 16, 16, &windowGraphics }; - Graphics graphics{ &bitmap }; - FontFamily fontFamily{ L"Microsoft Sans Serif" }; - Font font{ &fontFamily, m_count <= 99 ? (m_count < 10 ? 8.0f : 7.5f) : 7.0f }; - std::wstring countStr{ m_count > 99 ? L"99+" : std::to_wstring(m_count) }; - SizeF stringSize; - graphics.MeasureString(countStr.c_str(), (int)countStr.length(), &font, SizeF(16, 16), StringFormat::GenericDefault(), &stringSize); - graphics.FillEllipse(&background, Rect(0, 0, 16, 16)); - graphics.DrawString(countStr.c_str(), (int)countStr.length(), &font, PointF((16 - stringSize.Width) / 2, (16 - stringSize.Height) / 2), &foreground); - HICON icon{ nullptr }; - bitmap.GetHICON(&icon); - m_taskbar->SetOverlayIcon(m_hwnd, icon, std::to_wstring(m_count).c_str()); - DestroyIcon(icon); } #elif defined(__linux__) bool TaskbarItem::connect(const std::string& desktopFile)