diff --git a/AutoStart/AutoStart-Linux.cpp b/AutoStart/AutoStart-Linux.cpp new file mode 100644 index 00000000..f09f97e5 --- /dev/null +++ b/AutoStart/AutoStart-Linux.cpp @@ -0,0 +1,212 @@ +#include "AutoStart-Linux.h" +#include "LogManager.h" +#include "filesystem.h" + +#include +#include +#include +#include + +/*-----------------------------------------------------*\ +| Linux AutoStart Implementation | +| Public Methods | +\*-----------------------------------------------------*/ + +AutoStart::AutoStart(std::string name) +{ + InitAutoStart(name); +} + +bool AutoStart::DisableAutoStart() +{ + std::error_code autostart_file_remove_errcode; + bool success = false; + + /*-------------------------------------------------*\ + | Check if the filename is valid | + \*-------------------------------------------------*/ + if(autostart_file != "") + { + /*---------------------------------------------*\ + | If file doesn't exist, disable is successful | + \*---------------------------------------------*/ + if(!filesystem::exists(autostart_file)) + { + success = true; + } + /*---------------------------------------------*\ + | Otherwise, delete the file | + \*---------------------------------------------*/ + else + { + success = filesystem::remove(autostart_file, autostart_file_remove_errcode); + + if(!success) + { + LOG_ERROR("[AutoStart] An error occurred removing the auto start file."); + } + } + } + else + { + LOG_ERROR("Could not establish correct autostart file path."); + } + + return(success); +} + +bool AutoStart::EnableAutoStart(AutoStartInfo autostart_info) +{ + bool success = false; + + /*-------------------------------------------------*\ + | Check if the filename is valid | + \*-------------------------------------------------*/ + if(autostart_file != "") + { + std::string desktop_file = GenerateDesktopFile(autostart_info); + std::ofstream autostart_file_stream(autostart_file, std::ios::out | std::ios::trunc); + + /*---------------------------------------------*\ + | Error out if the file could not be opened | + \*---------------------------------------------*/ + if(!autostart_file_stream) + { + LOG_ERROR("Could not open %s for writing.", autostart_file.c_str()); + success = false; + } + /*---------------------------------------------*\ + | Otherwise, write the file | + \*---------------------------------------------*/ + else + { + autostart_file_stream << desktop_file; + autostart_file_stream.close(); + success = !autostart_file_stream.fail(); + + if (!success) + { + LOG_ERROR("An error occurred writing the auto start file."); + } + } + } + else + { + LOG_ERROR("Could not establish correct autostart file path."); + } + + return(success); +} + +bool AutoStart::IsAutoStartEnabled() +{ + /*-------------------------------------------------*\ + | Check if the filename is valid | + \*-------------------------------------------------*/ + if(autostart_file != "") + { + return(filesystem::exists(autostart_file)); + } + else + { + return(false); + } +} + +std::string AutoStart::GetExePath() +{ + /*-------------------------------------------------*\ + | Create the OpenRGB executable path | + \*-------------------------------------------------*/ + char exepath[ PATH_MAX ]; + + ssize_t count = readlink("/proc/self/exe", exepath, PATH_MAX); + + return(std::string(exepath, (count > 0) ? count : 0)); +} + +/*-----------------------------------------------------*\ +| Linux AutoStart Implementation | +| Private Methods | +\*-----------------------------------------------------*/ + +std::string AutoStart::GenerateDesktopFile(AutoStartInfo autostart_info) +{ + /*-------------------------------------------------*\ + | Generate a .desktop file from the AutoStart | + | parameters | + \*-------------------------------------------------*/ + std::stringstream fileContents; + + fileContents << "[Desktop Entry]" << std::endl; + fileContents << "Categories=" << autostart_info.category << std::endl; + fileContents << "Comment=" << autostart_info.desc << std::endl; + fileContents << "Icon=" << autostart_info.icon << std::endl; + fileContents << "Name=" << GetAutoStartName() << std::endl; + fileContents << "StartupNotify=true" << std::endl; + fileContents << "Terminal=false" << std::endl; + fileContents << "Type=Application" << std::endl; + + /*-------------------------------------------------*\ + | Add the executable path and arguments | + \*-------------------------------------------------*/ + fileContents << "Exec=" << autostart_info.path; + + if (autostart_info.args != "") + { + fileContents << " " << autostart_info.args; + } + + fileContents << std::endl; + + return(fileContents.str()); +} + +void AutoStart::InitAutoStart(std::string name) +{ + std::string autostart_dir; + + autostart_name = name; + + /*-------------------------------------------------*\ + | Get home and config paths | + \*-------------------------------------------------*/ + const char *xdg_config_home = getenv("XDG_CONFIG_HOME"); + const char *home = getenv("HOME"); + + /*-------------------------------------------------*\ + | Determine where the autostart .desktop files are | + | kept | + \*-------------------------------------------------*/ + if(xdg_config_home != NULL) + { + autostart_dir = xdg_config_home; + autostart_dir = autostart_dir + "/autostart/"; + } + else if(home != NULL) + { + autostart_dir = home; + autostart_dir = autostart_dir + "/.config/autostart/"; + } + + /*-------------------------------------------------*\ + | Check if the filename is valid | + \*-------------------------------------------------*/ + if(autostart_dir != "") + { + std::error_code ec; + + bool success = true; + + if(!filesystem::exists(autostart_dir)) + { + success = filesystem::create_directories(autostart_dir, ec); + } + + if(success) + { + autostart_file = autostart_dir + autostart_name + ".desktop"; + } + } +} + diff --git a/AutoStart/AutoStart-Linux.h b/AutoStart/AutoStart-Linux.h new file mode 100644 index 00000000..3ea43ec8 --- /dev/null +++ b/AutoStart/AutoStart-Linux.h @@ -0,0 +1,19 @@ +#pragma once + +#include +#include "AutoStart.h" + +class AutoStart: public AutoStartInterface +{ +public: + AutoStart(std::string name); + + bool DisableAutoStart(); + bool EnableAutoStart(AutoStartInfo autostart_info); + bool IsAutoStartEnabled(); + std::string GetExePath(); + +private: + void InitAutoStart(std::string name); + std::string GenerateDesktopFile(AutoStartInfo autostart_info); +}; diff --git a/AutoStart/AutoStart-MacOS.cpp b/AutoStart/AutoStart-MacOS.cpp new file mode 100644 index 00000000..32bad731 --- /dev/null +++ b/AutoStart/AutoStart-MacOS.cpp @@ -0,0 +1,181 @@ +#include "AutoStart-MacOS.h" +#include "LogManager.h" +#include "filesystem.h" + +#include +#include +#include + +/*-----------------------------------------------------*\ +| MacOS AutoStart Implementation | +| Public Methods | +\*-----------------------------------------------------*/ + +AutoStart::AutoStart(std::string name) +{ + InitAutoStart(name); +} + +bool AutoStart::DisableAutoStart() +{ + std::error_code autostart_file_remove_errcode; + bool success = false; + + // /*-------------------------------------------------*\ + // | Check if the filename is valid | + // \*-------------------------------------------------*/ + // if(autostart_file != "") + // { + // /*---------------------------------------------*\ + // | If file doesn't exist, disable is successful | + // \*---------------------------------------------*/ + // if(!filesystem::exists(autostart_file)) + // { + // success = true; + // } + // /*---------------------------------------------*\ + // | Otherwise, delete the file | + // \*---------------------------------------------*/ + // else + // { + // success = filesystem::remove(autostart_file, autostart_file_remove_errcode); + + // if(!success) + // { + // LOG_ERROR("[AutoStart] An error occurred removing the auto start file."); + // } + // } + // } + // else + // { + // LOG_ERROR("Could not establish correct autostart file path."); + // } + + return(success); +} + +bool AutoStart::EnableAutoStart(AutoStartInfo autostart_info) +{ + bool success = false; + + // /*-------------------------------------------------*\ + // | Check if the filename is valid | + // \*-------------------------------------------------*/ + // if(autostart_file != "") + // { + // std::string desktop_file = GenerateDesktopFile(autostart_info); + // std::ofstream autostart_file_stream(autostart_file, std::ios::out | std::ios::trunc); + + // /*---------------------------------------------*\ + // | Error out if the file could not be opened | + // \*---------------------------------------------*/ + // if(!autostart_file_stream) + // { + // LOG_ERROR("Could not open %s for writing.", autostart_file.c_str()); + // success = false; + // } + // /*---------------------------------------------*\ + // | Otherwise, write the file | + // \*---------------------------------------------*/ + // else + // { + // autostart_file_stream << desktop_file; + // autostart_file_stream.close(); + // success = !autostart_file_stream.fail(); + + // if (!success) + // { + // LOG_ERROR("An error occurred writing the auto start file."); + // } + // } + // } + // else + // { + // LOG_ERROR("Could not establish correct autostart file path."); + // } + + return(success); +} + +bool AutoStart::IsAutoStartEnabled() +{ + /*-------------------------------------------------*\ + | Check if the filename is valid | + \*-------------------------------------------------*/ + if(autostart_file != "") + { + return(filesystem::exists(autostart_file)); + } + else + { + return(false); + } +} + +std::string AutoStart::GetExePath() +{ + /*-------------------------------------------------*\ + | Create the OpenRGB executable path | + \*-------------------------------------------------*/ + // char exepath[ PATH_MAX ]; + + // ssize_t count = readlink("/proc/self/exe", exepath, PATH_MAX); + + // return(std::string(exepath, (count > 0) ? count : 0)); + + return(""); +} + +/*-----------------------------------------------------*\ +| MacOS AutoStart Implementation | +| Private Methods | +\*-----------------------------------------------------*/ + +void AutoStart::InitAutoStart(std::string name) +{ + std::string autostart_dir; + + autostart_name = name; + + // /*-------------------------------------------------*\ + // | Get home and config paths | + // \*-------------------------------------------------*/ + // const char *xdg_config_home = getenv("XDG_CONFIG_HOME"); + // const char *home = getenv("HOME"); + + // /*-------------------------------------------------*\ + // | Determine where the autostart .desktop files are | + // | kept | + // \*-------------------------------------------------*/ + // if(xdg_config_home != NULL) + // { + // autostart_dir = xdg_config_home; + // autostart_dir = autostart_dir + "/autostart/"; + // } + // else if(home != NULL) + // { + // autostart_dir = home; + // autostart_dir = autostart_dir + "/.config/autostart/"; + // } + + // /*-------------------------------------------------*\ + // | Check if the filename is valid | + // \*-------------------------------------------------*/ + // if(autostart_dir != "") + // { + // std::error_code ec; + + // bool success = true; + + // if(!filesystem::exists(autostart_dir)) + // { + // success = filesystem::create_directories(autostart_dir, ec); + // } + + // if(success) + // { + // autostart_file = autostart_dir + autostart_name + ".desktop"; + // } + // } +} + diff --git a/AutoStart/AutoStart-MacOS.h b/AutoStart/AutoStart-MacOS.h new file mode 100644 index 00000000..1c55e634 --- /dev/null +++ b/AutoStart/AutoStart-MacOS.h @@ -0,0 +1,18 @@ +#pragma once + +#include +#include "AutoStart.h" + +class AutoStart: public AutoStartInterface +{ +public: + AutoStart(std::string name); + + bool DisableAutoStart(); + bool EnableAutoStart(AutoStartInfo autostart_info); + bool IsAutoStartEnabled(); + std::string GetExePath(); + +private: + void InitAutoStart(std::string name); +}; diff --git a/AutoStart/AutoStart-Windows.cpp b/AutoStart/AutoStart-Windows.cpp new file mode 100644 index 00000000..3f2625c5 --- /dev/null +++ b/AutoStart/AutoStart-Windows.cpp @@ -0,0 +1,204 @@ +#include "AutoStart-Windows.h" +#include "LogManager.h" +#include "filesystem.h" + +#include +#include + +#include "windows.h" +#include + +/*-----------------------------------------------------*\ +| Windows AutoStart Implementation | +| Public Methods | +\*-----------------------------------------------------*/ + +AutoStart::AutoStart(std::string name) +{ + InitAutoStart(name); +} + +bool AutoStart::DisableAutoStart() +{ + std::error_code autostart_file_remove_errcode; + bool success = false; + + /*-------------------------------------------------*\ + | Check if the filename is valid | + \*-------------------------------------------------*/ + if(autostart_file != "") + { + /*---------------------------------------------*\ + | If file doesn't exist, disable is successful | + \*---------------------------------------------*/ + if(!filesystem::exists(autostart_file)) + { + success = true; + } + /*---------------------------------------------*\ + | Otherwise, delete the file | + \*---------------------------------------------*/ + else + { + success = filesystem::remove(autostart_file, autostart_file_remove_errcode); + + if(!success) + { + LOG_ERROR("An error occurred removing the auto start file."); + } + } + } + else + { + LOG_ERROR("Could not establish correct autostart file path."); + } + + return(success); +} + +bool AutoStart::EnableAutoStart(AutoStartInfo autostart_info) +{ + bool success = false; + + /*-------------------------------------------------*\ + | Check if the filename is valid | + \*-------------------------------------------------*/ + if(autostart_file != "") + { + bool weInitialised = false; + HRESULT result; + IShellLinkW* shellLink = NULL; + + std::wstring exepathw = utf8_decode(autostart_info.path); + std::wstring argumentsw = utf8_decode(autostart_info.args); + std::wstring startupfilepathw = utf8_decode(autostart_file); + std::wstring descriptionw = utf8_decode(autostart_info.desc); + std::wstring iconw = utf8_decode(autostart_info.path); + + result = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_ALL, IID_IShellLinkW, (void**)&shellLink); + + /*---------------------------------------------*\ + | If not initialized, initialize | + \*---------------------------------------------*/ + if(result == CO_E_NOTINITIALIZED) + { + weInitialised = true; + CoInitializeEx(NULL, 2u); + result = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_ALL, IID_IShellLinkW, (void**)&shellLink); + } + + /*---------------------------------------------*\ + | If successfully initialized, save a shortcut | + | from the AutoStart parameters | + \*---------------------------------------------*/ + if(SUCCEEDED(result)) + { + shellLink->SetPath(exepathw.c_str()); + shellLink->SetArguments(argumentsw.c_str()); + shellLink->SetDescription(descriptionw.c_str()); + shellLink->SetIconLocation(iconw.c_str(), 0); + + IPersistFile* persistFile; + + result = shellLink->QueryInterface(IID_IPersistFile, (void**)&persistFile); + + if(SUCCEEDED(result)) + { + result = persistFile->Save(startupfilepathw.c_str(), TRUE); + success = SUCCEEDED(result); + persistFile->Release(); + } + + shellLink->Release(); + } + + /*---------------------------------------------*\ + | Uninitialize when done | + \*---------------------------------------------*/ + if(weInitialised) + { + CoUninitialize(); + } + } + else + { + LOG_ERROR("Could not establish correct autostart file path."); + } + + return success; +} + +bool AutoStart::IsAutoStartEnabled() +{ + /*-------------------------------------------------*\ + | Check if the filename is valid | + \*-------------------------------------------------*/ + if(autostart_file != "") + { + return(filesystem::exists(autostart_file)); + } + else + { + return(false); + } +} + +std::string AutoStart::GetExePath() +{ + /*-------------------------------------------------*\ + | Create the OpenRGB executable path | + \*-------------------------------------------------*/ + char exepath[MAX_PATH] = ""; + + DWORD count = GetModuleFileNameA(NULL, exepath, MAX_PATH); + + return(std::string(exepath, (count > 0) ? count : 0)); +} + +/*-----------------------------------------------------*\ +| Windows AutoStart Implementation | +| Private Methods | +\*-----------------------------------------------------*/ + +void AutoStart::InitAutoStart(std::string name) +{ + char startMenuPath[MAX_PATH]; + + autostart_name = name; + + /*-------------------------------------------------*\ + | Get startup applications path | + \*-------------------------------------------------*/ + HRESULT result = SHGetFolderPathA(NULL, CSIDL_PROGRAMS, NULL, 0, startMenuPath); + + if(SUCCEEDED(result)) + { + autostart_file = std::string(startMenuPath); + + autostart_file += "\\Startup\\" + autostart_name + ".lnk"; + } + else + { + autostart_file.clear(); + } +} + +/*-----------------------------------------------------*\ +| Convert an UTF8 string to a wide Unicode String | +| (from wmi.cpp) | +\*-----------------------------------------------------*/ +std::wstring AutoStart::utf8_decode(const std::string& str) +{ + if(str.empty()) + { + return std::wstring(); + } + + int size_needed = MultiByteToWideChar(CP_UTF8, 0, &str[0], (int) str.size(), nullptr, 0); + + std::wstring wstrTo(size_needed, 0); + + MultiByteToWideChar(CP_UTF8, 0, &str[0], (int) str.size(), &wstrTo[0], size_needed); + + return(wstrTo); +} diff --git a/AutoStart/AutoStart-Windows.h b/AutoStart/AutoStart-Windows.h new file mode 100644 index 00000000..017ec59a --- /dev/null +++ b/AutoStart/AutoStart-Windows.h @@ -0,0 +1,19 @@ +#pragma once + +#include +#include "AutoStart.h" + +class AutoStart: public AutoStartInterface +{ +public: + AutoStart(std::string name); + + bool DisableAutoStart(); + bool EnableAutoStart(AutoStartInfo autostart_info); + bool IsAutoStartEnabled(); + std::string GetExePath(); + +private: + void InitAutoStart(std::string name); + std::wstring utf8_decode(const std::string& str); +}; diff --git a/AutoStart/AutoStart.cpp b/AutoStart/AutoStart.cpp new file mode 100644 index 00000000..a483e29d --- /dev/null +++ b/AutoStart/AutoStart.cpp @@ -0,0 +1,16 @@ +#include "AutoStart.h" + +/*-----------------------------------------------------*\ +| Common AutoStart Implementation | +| Public Methods | +\*-----------------------------------------------------*/ + +std::string AutoStartInterface::GetAutoStartFile() +{ + return(autostart_file); +} + +std::string AutoStartInterface::GetAutoStartName() +{ + return(autostart_name); +} diff --git a/AutoStart/AutoStart.h b/AutoStart/AutoStart.h new file mode 100644 index 00000000..f2dda1fb --- /dev/null +++ b/AutoStart/AutoStart.h @@ -0,0 +1,40 @@ +#pragma once + +#include + +struct AutoStartInfo +{ + std::string path; + std::string args; + std::string desc; + std::string icon; + std::string category; +}; + +class AutoStartInterface +{ +public: + virtual bool DisableAutoStart() = 0; + virtual bool EnableAutoStart(AutoStartInfo autostart_info) = 0; + virtual bool IsAutoStartEnabled() = 0; + virtual std::string GetExePath() = 0; + + std::string GetAutoStartFile(); + std::string GetAutoStartName(); + +protected: + std::string autostart_file; + std::string autostart_name; +}; + +#ifdef _WIN32 +#include "AutoStart-Windows.h" +#endif + +#ifdef __linux__ +#include "AutoStart-Linux.h" +#endif + +#ifdef __APPLE__ +#include "AutoStart-MacOS.h" +#endif \ No newline at end of file diff --git a/OpenRGB.pro b/OpenRGB.pro index 4283ee71..c786b8d6 100644 --- a/OpenRGB.pro +++ b/OpenRGB.pro @@ -60,6 +60,7 @@ INCLUDEPATH += pci_ids/ \ serial_port/ \ super_io/ \ + AutoStart/ \ Controllers/AMDWraithPrismController/ \ Controllers/ASRockPolychromeSMBusController/ \ Controllers/ASRockPolychromeUSBController/ \ @@ -170,6 +171,7 @@ HEADERS += serial_port/find_usb_serial_port.h \ serial_port/serial_port.h \ super_io/super_io.h \ + AutoStart/AutoStart.h \ Controllers/AMDWraithPrismController/AMDWraithPrismController.h \ Controllers/AMDWraithPrismController/RGBController_AMDWraithPrism.h \ Controllers/AnnePro2Controller/AnnePro2Controller.h \ @@ -458,6 +460,7 @@ SOURCES += qt/hsv.cpp \ serial_port/serial_port.cpp \ super_io/super_io.cpp \ + AutoStart/AutoStart.cpp \ Controllers/AMDWraithPrismController/AMDWraithPrismController.cpp \ Controllers/AMDWraithPrismController/AMDWraithPrismControllerDetect.cpp \ Controllers/AMDWraithPrismController/RGBController_AMDWraithPrism.cpp \ @@ -875,6 +878,7 @@ win32:SOURCES += serial_port/find_usb_serial_port_win.cpp \ wmi/wmi.cpp \ wmi/acpiwmi.cpp \ + AutoStart/AutoStart-Windows.cpp \ Controllers/AsusTUFLaptopController/AsusTUFLaptopWMIDetect.cpp \ Controllers/AsusTUFLaptopController/RGBController_AsusTUFLaptopWMI.cpp \ Controllers/OpenRazerController/OpenRazerWindowsDetect.cpp \ @@ -892,6 +896,7 @@ win32:HEADERS += i2c_smbus/i2c_smbus_piix4.h \ wmi/wmi.h \ wmi/acpiwmi.h \ + AutoStart/AutoStart-Windows.h \ Controllers/AsusTUFLaptopController/RGBController_AsusTUFLaptopWMI.h \ Controllers/OpenRazerController/RGBController_OpenRazerWindows.h \ @@ -980,6 +985,7 @@ unix:!macx { HEADERS += \ i2c_smbus/i2c_smbus_linux.h \ + AutoStart/AutoStart-Linux.h \ Controllers/FaustusController/RGBController_Faustus.h \ Controllers/LinuxLEDController/LinuxLEDController.h \ Controllers/LinuxLEDController/RGBController_LinuxLED.h \ @@ -1019,6 +1025,7 @@ unix:!macx { dependencies/hueplusplus-1.0.0/src/LinHttpHandler.cpp \ i2c_smbus/i2c_smbus_linux.cpp \ serial_port/find_usb_serial_port_linux.cpp \ + AutoStart/AutoStart-Linux.cpp \ Controllers/FaustusController/RGBController_Faustus.cpp \ Controllers/LinuxLEDController/LinuxLEDController.cpp \ Controllers/LinuxLEDController/LinuxLEDControllerDetect.cpp \ @@ -1065,9 +1072,13 @@ macx { DEFINES += \ USE_HID_USAGE \ + HEADERS += \ + AutoStart/AutoStart-MacOS.h \ + SOURCES += \ dependencies/hueplusplus-1.0.0/src/LinHttpHandler.cpp \ serial_port/find_usb_serial_port_linux.cpp \ + AutoStart/AutoStart-MacOS.cpp \ LIBS += \ -lusb-1.0 \ diff --git a/cli.cpp b/cli.cpp index 1b43915e..9a4003f6 100644 --- a/cli.cpp +++ b/cli.cpp @@ -4,6 +4,7 @@ #include #include #include "OpenRGB.h" +#include "AutoStart.h" #include "ProfileManager.h" #include "ResourceManager.h" #include "RGBController.h" @@ -402,6 +403,9 @@ void OptionHelp() help_text += "--print-source Print the source code file and line number for each log entry.\n"; help_text += "-v, --verbose Print log messages to stdout.\n"; help_text += "-vv, --very-verbose Print debug messages and log messages to stdout.\n"; + help_text += "--autostart-check Check if OpenRGB starting at login is enabled.\n"; + help_text += "--autostart-disable Disable OpenRGB starting at login.\n"; + help_text += "--autostart-enable arguments Enable OpenRGB to start at login. Requires arguments to give to OpenRGB at login.\n"; std::cout << help_text << std::endl; } @@ -833,7 +837,9 @@ int ProcessOptions(int argc, char *argv[], Options *options, std::vectorGetSettingsManager()->GetSettings("UserInterface"); @@ -56,6 +57,68 @@ OpenRGBSettingsPage::OpenRGBSettingsPage(QWidget *parent) : ui->CheckboxSaveGeometry->setChecked(ui_settings["geometry"]["save_on_exit"]); } } + + /*---------------------------------------------------------*\ + | Load AutoStart settings | + \*---------------------------------------------------------*/ + ProfileManager* profile_manager = ResourceManager::get()->GetProfileManager(); + + /*---------------------------------------------------------*\ + | Load profiles into combo box | + \*---------------------------------------------------------*/ + if(profile_manager != NULL) + { + ui->ComboBoxAutoStartProfile->clear(); + + for(std::size_t profile_index = 0; profile_index < profile_manager->profile_list.size(); profile_index++) + { + ui->ComboBoxAutoStartProfile->addItem(profile_manager->profile_list[profile_index].c_str()); + } + } + + /*---------------------------------------------------------*\ + | Make sure autostart settings exist | + \*---------------------------------------------------------*/ + CreateAutoStartSettings(); + + /*---------------------------------------------------------*\ + | Initialise UI to current settings or defaults | + \*---------------------------------------------------------*/ + json autostart_settings = ResourceManager::get()->GetSettingsManager()->GetSettings("AutoStart"); + + RemediateAutoStartProfile(autostart_settings); + + /*---------------------------------------------------------*\ + | Text boxes | + \*---------------------------------------------------------*/ + ui->TextServerPort->setText(QString::fromStdString(autostart_settings["port"])); + ui->TextServerPort->setEnabled(autostart_settings["setserverport"]); + + ui->TextClientHost->setText(QString::fromStdString(autostart_settings["client"])); + ui->TextClientHost->setEnabled(autostart_settings["setclient"]); + + ui->TextCustomArgs->setText(QString::fromStdString(autostart_settings["custom"])); + ui->TextCustomArgs->setEnabled(autostart_settings["setcustom"]); + + /*---------------------------------------------------------*\ + | Checkboxes | + \*---------------------------------------------------------*/ + ui->CheckboxAutoStart->setChecked(autostart_settings["enabled"]); + SetAutoStartVisibility(autostart_settings["enabled"]); + + ui->CheckboxAutoStartMinimized->setChecked(autostart_settings["setminimized"]); + ui->CheckboxAutoStartClient->setChecked(autostart_settings["setclient"]); + ui->CheckboxAutoStartServer->setChecked(autostart_settings["setserver"]); + ui->CheckboxAutoStartSetServerPort->setChecked(autostart_settings["setserverport"]); + ui->CheckboxAutoStartCustom->setChecked(autostart_settings["setcustom"]); + + ui->AutoStartStatusLabel->hide(); + autostart_initialized = true; + +#ifdef __APPLE__ + SetAutoStartVisibility(false); + ui->CheckboxAutoStart->hide(); +#endif } OpenRGBSettingsPage::~OpenRGBSettingsPage() @@ -98,6 +161,329 @@ void Ui::OpenRGBSettingsPage::on_CheckboxSaveGeometry_clicked() SaveSettings(); } +void Ui::OpenRGBSettingsPage::on_CheckboxAutoStart_clicked() +{ + if(autostart_initialized) + { + json autostart_settings = ResourceManager::get()->GetSettingsManager()->GetSettings("AutoStart"); + autostart_settings["enabled"] = ui->CheckboxAutoStart->isChecked(); + + if(autostart_settings["enabled"]) + { + RemediateAutoStartProfile(autostart_settings); + } + + ResourceManager::get()->GetSettingsManager()->SetSettings("AutoStart", autostart_settings); + SaveSettings(); + + SetAutoStartVisibility(autostart_settings["enabled"]); + + ConfigureAutoStart(); + } +} + +void Ui::OpenRGBSettingsPage::on_CheckboxAutoStartMinimized_clicked() +{ + SaveAutoStartSetting("setminimized", ui->CheckboxAutoStartMinimized->isChecked()); +} + +void Ui::OpenRGBSettingsPage::on_CheckboxAutoStartServer_clicked() +{ + SaveAutoStartSetting("setserver", ui->CheckboxAutoStartServer->isChecked()); +} + +void Ui::OpenRGBSettingsPage::on_CheckboxAutoStartSetServerPort_clicked() +{ + SaveAutoStartSetting("setserverport", ui->CheckboxAutoStartSetServerPort->isChecked()); + ui->TextServerPort->setEnabled(ui->CheckboxAutoStartSetServerPort->isChecked()); +} + +void Ui::OpenRGBSettingsPage::on_CheckboxAutoStartClient_clicked() +{ + SaveAutoStartSetting("setclient", ui->CheckboxAutoStartClient->isChecked()); + ui->TextClientHost->setEnabled(ui->CheckboxAutoStartClient->isChecked()); +} + +void Ui::OpenRGBSettingsPage::on_CheckboxAutoStartProfile_clicked() +{ + SaveAutoStartSetting("setprofile", ui->CheckboxAutoStartProfile->isChecked()); + ui->ComboBoxAutoStartProfile->setEnabled(ui->CheckboxAutoStartProfile->isChecked()); +} + +void Ui::OpenRGBSettingsPage::on_CheckboxAutoStartCustom_clicked() +{ + SaveAutoStartSetting("setcustom", ui->CheckboxAutoStartCustom->isChecked()); + ui->TextCustomArgs->setEnabled(ui->CheckboxAutoStartCustom->isChecked()); +} + +void Ui::OpenRGBSettingsPage::on_TextServerPort_textChanged(QString port) +{ + SaveAutoStartSetting("port", port); +} + +void Ui::OpenRGBSettingsPage::on_TextClientHost_textChanged(QString client) +{ + SaveAutoStartSetting("client", client); +} + +void Ui::OpenRGBSettingsPage::on_TextCustomArgs_textChanged(QString custom) +{ + SaveAutoStartSetting("custom", custom); +} + +void Ui::OpenRGBSettingsPage::on_ComboBoxAutoStartProfile_currentTextChanged(const QString profile) +{ + SaveAutoStartSetting("profile", profile); +} + +void OpenRGBSettingsPage::SaveAutoStartSetting(std::string name, QString value) +{ + if(autostart_initialized) + { + json autostart_settings = ResourceManager::get()->GetSettingsManager()->GetSettings("AutoStart"); + autostart_settings[name] = value.toStdString(); + ResourceManager::get()->GetSettingsManager()->SetSettings("AutoStart", autostart_settings); + SaveSettings(); + + ConfigureAutoStart(); + } +} + +void OpenRGBSettingsPage::SaveAutoStartSetting(std::string name, bool value) +{ + if(autostart_initialized) + { + json autostart_settings = ResourceManager::get()->GetSettingsManager()->GetSettings("AutoStart"); + autostart_settings[name] = value; + ResourceManager::get()->GetSettingsManager()->SetSettings("AutoStart", autostart_settings); + SaveSettings(); + + ConfigureAutoStart(); + } +} + +void OpenRGBSettingsPage::SetAutoStartVisibility(bool visible) +{ + if (!visible) + { + ui->ComboBoxAutoStartProfile->hide(); + ui->CheckboxAutoStartClient->hide(); + ui->CheckboxAutoStartCustom->hide(); + ui->CheckboxAutoStartMinimized->hide(); + ui->CheckboxAutoStartProfile->hide(); + ui->CheckboxAutoStartServer->hide(); + ui->CheckboxAutoStartSetServerPort->hide(); + ui->TextCustomArgs->hide(); + ui->TextClientHost->hide(); + ui->TextServerPort->hide(); + ui->AutoStartLabel->hide(); + ui->AutoStartStatusLabel->hide(); + } + else + { + ui->ComboBoxAutoStartProfile->show(); + ui->CheckboxAutoStartClient->show(); + ui->CheckboxAutoStartCustom->show(); + ui->CheckboxAutoStartMinimized->show(); + ui->CheckboxAutoStartProfile->show(); + ui->CheckboxAutoStartServer->show(); + ui->CheckboxAutoStartSetServerPort->show(); + ui->TextCustomArgs->show(); + ui->TextClientHost->show(); + ui->TextServerPort->show(); + ui->AutoStartLabel->show(); + ui->AutoStartStatusLabel->show(); + } +} + +void OpenRGBSettingsPage::ConfigureAutoStart() +{ + std::map> autostart_map = { + {"setminimized", {"--startminimized","",false}}, + {"setserver", {"--server","",false}}, + {"setserverport", {"--server-port","port",false}}, + {"setclient", {"--client","client",false}}, + {"setprofile", {"--profile","profile",true}}, + {"setcustom", {"","custom",false}}, + }; + + json autostart_settings = ResourceManager::get()->GetSettingsManager()->GetSettings("AutoStart"); + + AutoStart auto_start("OpenRGB"); + + if (!autostart_settings["enabled"]) + { + if (!auto_start.DisableAutoStart()) + { + ui->AutoStartStatusLabel->setText("A problem occurred disabling Start At Login."); + ui->AutoStartStatusLabel->show(); + SetAutoStartVisibility(true); + } + else + { + ui->AutoStartStatusLabel->hide(); + } + } + else + { + std::string desc = "OpenRGB "; + desc += VERSION_STRING; + desc += ", for controlling RGB lighting."; + + std::string arguments = ""; + + for(std::pair>& x: autostart_map) + { + std::string argumentsetting = x.first; + std::string argument = std::get<0>(x.second); + std::string argumentvaluename = std::get<1>(x.second); + bool argumentquoted = std::get<2>(x.second); + + if (autostart_settings[x.first]) + { + if (argument != "") + { + if (arguments != "") + { + arguments += " "; + } + arguments += argument; + } + if (argumentvaluename != "") + { + std::string argumentvalue = autostart_settings[argumentvaluename]; + if (argumentvalue != "") + { + if (arguments != "") + { + arguments += " "; + } + if (argumentquoted) + { + arguments += "\"" + argumentvalue + "\""; + } + else + { + arguments += argumentvalue; + } + } + } + } + } + + AutoStartInfo auto_start_info; + + auto_start_info.args = arguments; + auto_start_info.category = "Utility;"; + auto_start_info.desc = desc; + auto_start_info.icon = "OpenRGB"; + auto_start_info.path = auto_start.GetExePath(); + + if (!auto_start.EnableAutoStart(auto_start_info)) + { + ui->AutoStartStatusLabel->setText("A problem occurred enabling Start At Login."); + ui->AutoStartStatusLabel->show(); + SetAutoStartVisibility(true); + } + else + { + ui->AutoStartStatusLabel->hide(); + } + } +} + +void OpenRGBSettingsPage::CreateAutoStartSettings() +{ + std::map autostart_default_map_string = { + {"custom", ""}, + {"port", "6742"}, + {"client","localhost:6742"}, + {"profile",ui->ComboBoxAutoStartProfile->count() > 0 ? ui->ComboBoxAutoStartProfile->itemText(0).toStdString(): ""} + }; + + std::map autostart_default_map_bool = { + {"enabled", false}, + {"setminimized", false}, + {"setclient", false}, + {"setserver", false}, + {"setserverport", false}, + {"setcustom", false}, + {"setprofile", false}, + }; + + json autostart_settings = ResourceManager::get()->GetSettingsManager()->GetSettings("AutoStart"); + + for(std::pair& x: autostart_default_map_bool) + { + if(!autostart_settings.contains(x.first)) + { + autostart_settings[x.first] = x.second; + } + } + + for(std::pair& x: autostart_default_map_string) + { + if(!autostart_settings.contains(x.first)) + { + autostart_settings[x.first] = x.second; + } + } + + ResourceManager::get()->GetSettingsManager()->SetSettings("AutoStart", autostart_settings); +} + +void OpenRGBSettingsPage::RemediateAutoStartProfile(json &autostart_settings) +{ + /*---------------------------------------------------------*\ + | If there are no profiles then we disable the UI for | + | profiles and if AutoStart is enabled then we force | + | disable setprofile | + \*---------------------------------------------------------*/ + if(ui->ComboBoxAutoStartProfile->count() == 0) + { + ui->CheckboxAutoStartProfile->setEnabled(false); + ui->ComboBoxAutoStartProfile->setEnabled(false); + + autostart_settings["profile"] = ""; + + if(autostart_settings["enabled"]) + { + autostart_settings["setprofile"] = false; + + ResourceManager::get()->GetSettingsManager()->SetSettings("AutoStart", autostart_settings); + + ConfigureAutoStart(); + SaveSettings(); + } + } + + /*---------------------------------------------------------*\ + | Else If the profile we want doesn't exist then we force | + | it to a profile which exists and if AutoStart is enabled | + | then we force disable setprofile | + \*---------------------------------------------------------*/ + else if(autostart_settings["profile"] == "" || + (autostart_settings["profile"] != "" && + ui->ComboBoxAutoStartProfile->findText(QString::fromStdString(autostart_settings["profile"])) == -1)) + { + autostart_settings["profile"] = ui->ComboBoxAutoStartProfile->itemText(0).toStdString(); + + if(autostart_settings["enabled"]) + { + autostart_settings["setprofile"] = false; + + ResourceManager::get()->GetSettingsManager()->SetSettings("AutoStart", autostart_settings); + + ConfigureAutoStart(); + SaveSettings(); + } + } + + ui->ComboBoxAutoStartProfile->setCurrentText(QString::fromStdString(autostart_settings["profile"])); + ui->ComboBoxAutoStartProfile->setEnabled(autostart_settings["setprofile"]); + ui->CheckboxAutoStartProfile->setChecked(autostart_settings["setprofile"]); +} + void OpenRGBSettingsPage::SaveSettings() { ResourceManager::get()->GetSettingsManager()->SaveSettings(); diff --git a/qt/OpenRGBSettingsPage.h b/qt/OpenRGBSettingsPage.h index 9705174a..ebd5ac07 100644 --- a/qt/OpenRGBSettingsPage.h +++ b/qt/OpenRGBSettingsPage.h @@ -3,6 +3,7 @@ #include "ui_OpenRGBSettingsPage.h" #include +#include "ResourceManager.h" namespace Ui { class OpenRGBSettingsPage; @@ -20,13 +21,32 @@ private: Ui::OpenRGBSettingsPageUi *ui; void SaveSettings(); + void CreateAutoStartSettings(); + void ConfigureAutoStart(); + void RemediateAutoStartProfile(json &autostart_settings); + void SetAutoStartVisibility(bool visible); + void SaveAutoStartSetting(std::string name, QString value); + void SaveAutoStartSetting(std::string name, bool value); + bool theme_initialized = false; + bool autostart_initialized = false; private slots: void on_ComboBoxTheme_currentTextChanged(const QString); void on_CheckboxMinimizeOnClose_clicked(); void on_CheckboxLoadGeometry_clicked(); void on_CheckboxSaveGeometry_clicked(); + void on_CheckboxAutoStart_clicked(); + void on_CheckboxAutoStartMinimized_clicked(); + void on_CheckboxAutoStartServer_clicked(); + void on_CheckboxAutoStartClient_clicked(); + void on_CheckboxAutoStartProfile_clicked(); + void on_TextServerPort_textChanged(const QString); + void on_TextClientHost_textChanged(const QString); + void on_TextCustomArgs_textChanged(const QString); + void on_ComboBoxAutoStartProfile_currentTextChanged(const QString); + void on_CheckboxAutoStartSetServerPort_clicked(); + void on_CheckboxAutoStartCustom_clicked(); }; #endif // OPENRGBSETTINGSPAGE_H diff --git a/qt/OpenRGBSettingsPage.ui b/qt/OpenRGBSettingsPage.ui index 67c30c74..707f7e24 100644 --- a/qt/OpenRGBSettingsPage.ui +++ b/qt/OpenRGBSettingsPage.ui @@ -7,18 +7,28 @@ 0 0 432 - 144 + 500 Form - + + + + Set Server Port + + + + Qt::Vertical + + QSizePolicy::MinimumExpanding + 20 @@ -27,37 +37,115 @@ - - - - Load Window Geometry - - - - - - - - - Minimize On Close - - - - Theme - + + + + + + + + + + Minimize On Close + + + + + + + Start Server + + + + + + + Start At Login + + + + + + + 90000 + + + + + + + + + + + + + Load Profile + + + + + + + Start Client + + + + + + + Start Minimized + + + + Save Geometry On Close + + + + Start at Login Status + + + + + + + Start At Login Settings: + + + + + + + + + + Load Window Geometry + + + + + + + Custom Arguments + + + + + +