From 16a481faa3d3096efdbedfa21cc65a6b521277b2 Mon Sep 17 00:00:00 2001 From: Odizinne Date: Sun, 1 Sep 2024 13:02:07 +0200 Subject: [PATCH] dissociated tray icon and config ui --- BigPictureTV.pro | 11 +- src/BigPictureTV/bigpicturetv.cpp | 354 +++--------------- src/BigPictureTV/bigpicturetv.h | 97 ++--- src/Configurator/configurator.cpp | 284 ++++++++++++++ src/Configurator/configurator.h | 65 ++++ .../configurator.ui} | 4 +- 6 files changed, 443 insertions(+), 372 deletions(-) create mode 100644 src/Configurator/configurator.cpp create mode 100644 src/Configurator/configurator.h rename src/{BigPictureTV/bigpicturetv.ui => Configurator/configurator.ui} (99%) diff --git a/BigPictureTV.pro b/BigPictureTV.pro index c0bf591..aa4e522 100644 --- a/BigPictureTV.pro +++ b/BigPictureTV.pro @@ -18,8 +18,9 @@ DEFINES += \ GIT_COMMIT_DATE=\"\"\"$$GIT_COMMIT_DATE\"\"\" INCLUDEPATH += \ - src/AudioManager \ + src/AudioManager\ src/BigPictureTV \ + src/Configurator \ src/NightLightSwitcher \ src/ShortcutManager \ src/SteamWindowManager \ @@ -27,23 +28,25 @@ INCLUDEPATH += \ SOURCES += \ src/AudioManager/audiomanager.cpp \ + src/BigPictureTV/BigPictureTV.cpp \ src/main.cpp \ src/NightLightSwitcher/NightLightSwitcher.cpp \ - src/BigPictureTV/bigpicturetv.cpp \ + src/Configurator/configurator.cpp \ src/ShortcutManager/shortcutmanager.cpp \ src/SteamWindowManager/steamwindowmanager.cpp \ src/Utils/utils.cpp HEADERS += \ src/AudioManager/audiomanager.h \ - src/BigPictureTV/bigpicturetv.h \ + src/BigPictureTV/BigPictureTV.h \ + src/Configurator/configurator.h \ src/NightLightSwitcher/NightLightSwitcher.h \ src/ShortcutManager/shortcutmanager.h \ src/SteamWindowManager/steamwindowmanager.h \ src/Utils/utils.h FORMS += \ - src/BigPictureTV/bigpicturetv.ui + src/Configurator/configurator.ui TRANSLATIONS += \ src/Resources/Tr/BigPictureTV_fr.ts \ diff --git a/src/BigPictureTV/bigpicturetv.cpp b/src/BigPictureTV/bigpicturetv.cpp index e237ad3..8136ac1 100644 --- a/src/BigPictureTV/bigpicturetv.cpp +++ b/src/BigPictureTV/bigpicturetv.cpp @@ -1,232 +1,66 @@ #include "bigpicturetv.h" -#include "ui_bigpicturetv.h" -#include -#include +#include #include -#include #include -#include +#include +#include +#include +#include const QString BigPictureTV::settingsFile = QStandardPaths::writableLocation( QStandardPaths::AppDataLocation) + "/BigPictureTV/settings.json"; -BigPictureTV::BigPictureTV(QWidget *parent) - : QMainWindow(parent) - , gamemodeActive(false) - , nightLightSwitcher(new NightLightSwitcher()) - , audioManager(new AudioManager()) - , steamWindowManager(new SteamWindowManager()) - , shortcutManager(new ShortcutManager()) +BigPictureTV::BigPictureTV(QObject *parent) + : QObject(parent) , utils(new Utils()) - , firstRun(false) + , steamWindowManager(new SteamWindowManager()) + , audioManager(new AudioManager()) + , nightLightSwitcher(new NightLightSwitcher()) , activePowerPlan("") , nightLightState(false) , discordState(false) - , ui(new Ui::BigPictureTV) , windowCheckTimer(new QTimer(this)) { - ui->setupUi(this); - setWindowIcon(utils->getIconForTheme()); - setupInfoTab(); - populateComboboxes(); loadSettings(); - setupConnections(); - getAudioCapabilities(); - windowCheckTimer->setInterval(ui->checkrateSpinBox->value()); + windowCheckTimer->setInterval(settings.value("checkrate").toInt()); connect(windowCheckTimer, &QTimer::timeout, this, &BigPictureTV::checkWindowTitle); windowCheckTimer->start(); createTrayIcon(); - if (firstRun) { - this->show(); - } } BigPictureTV::~BigPictureTV() { - saveSettings(); - delete steamWindowManager; - delete nightLightSwitcher; - delete ui; -} - -void BigPictureTV::setupConnections() -{ - connect(ui->startupCheckBox, &QCheckBox::stateChanged, this, &BigPictureTV::onStartupCheckboxStateChanged); - connect(ui->desktopAudioLineEdit, &QLineEdit::textChanged, this, &BigPictureTV::saveSettings); - connect(ui->gamemodeAudioLineEdit, &QLineEdit::textChanged, this, &BigPictureTV::saveSettings); - connect(ui->disableAudioCheckBox, &QCheckBox::checkStateChanged, this, &BigPictureTV::onDisableAudioCheckboxStateChanged); - connect(ui->disableMonitorCheckBox, &QCheckBox::stateChanged, this, &BigPictureTV::onDisableMonitorCheckboxStateChanged); - connect(ui->checkrateSpinBox, &QSpinBox::valueChanged, this, &BigPictureTV::onCheckrateSpinBoxValueChanged); - connect(ui->closeDiscordCheckBox, &QCheckBox::stateChanged, this, &BigPictureTV::saveSettings); - connect(ui->pauseMediaAction, &QCheckBox::stateChanged, this, &BigPictureTV::saveSettings); - connect(ui->enablePerformancePowerPlan, &QCheckBox::stateChanged, this, &BigPictureTV::saveSettings); - connect(ui->desktopMonitorComboBox, &QComboBox::currentIndexChanged, this, &BigPictureTV::saveSettings); - connect(ui->gamemodeMonitorComboBox, &QComboBox::currentIndexChanged, this, &BigPictureTV::saveSettings); - connect(ui->installAudioButton, &QPushButton::clicked, this, &BigPictureTV::onAudioButtonClicked); - connect(ui->targetWindowComboBox, &QComboBox::currentIndexChanged, this, &BigPictureTV::onTargetWindowComboBoxIndexChanged); - connect(ui->resetSettingsButton, &QPushButton::clicked, this, &BigPictureTV::createDefaultSettings); - connect(ui->openSettingsButton, &QPushButton::clicked, this, []() { - QString settingsFolder = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation); - QDesktopServices::openUrl(QUrl::fromLocalFile(settingsFolder)); - }); - - ui->startupCheckBox->setChecked(shortcutManager->isShortcutPresent()); - initDiscordAction(); -} -void BigPictureTV::initDiscordAction() -{ - if (!utils->isDiscordInstalled()) { - ui->closeDiscordCheckBox->setChecked(false); - ui->closeDiscordCheckBox->setEnabled(false); - ui->CloseDiscordLabel->setEnabled(false); - ui->closeDiscordCheckBox->setToolTip(tr("Discord does not appear to be installed")); - ui->CloseDiscordLabel->setToolTip(tr("Discord does not appear to be installed")); - } -} -void BigPictureTV::getAudioCapabilities() -{ - if (!utils->isAudioDeviceCmdletsInstalled()) { - ui->disableAudioCheckBox->setChecked(true); - ui->disableAudioCheckBox->setEnabled(false); - toggleAudioSettings(false); - } else { - ui->disableAudioCheckBox->setEnabled(true); - ui->installAudioButton->setEnabled(false); - ui->installAudioButton->setText(tr("Audio module installed")); - if (!ui->disableAudioCheckBox->isChecked()) { - toggleAudioSettings(true); - } - } } -void BigPictureTV::populateComboboxes() +void BigPictureTV::onActionTriggered() { - ui->desktopMonitorComboBox->addItem(tr("Internal")); - ui->desktopMonitorComboBox->addItem(tr("Extend")); - ui->gamemodeMonitorComboBox->addItem(tr("External")); - ui->gamemodeMonitorComboBox->addItem(tr("Clone")); - - ui->targetWindowComboBox->addItem(tr("Big Picture")); - ui->targetWindowComboBox->addItem(tr("Custom")); + QMessageBox::information(nullptr, tr("Tray Icon"), tr("Tray icon action triggered!")); } void BigPictureTV::createTrayIcon() { trayIcon = new QSystemTrayIcon(utils->getIconForTheme(), this); - trayIcon->setToolTip("BigPictureTV"); - trayIcon->setContextMenu(createMenu()); - trayIcon->show(); -} - -QMenu *BigPictureTV::createMenu() -{ - QMenu *menu = new QMenu(this); - - QAction *settingsAction = new QAction(tr("Settings"), this); - connect(settingsAction, &QAction::triggered, this, &BigPictureTV::showSettings); - - QAction *exitAction = new QAction(tr("Exit"), this); - connect(exitAction, &QAction::triggered, QApplication::instance(), &QApplication::quit); - - menu->addAction(settingsAction); - menu->addAction(exitAction); - - return menu; -} - -void BigPictureTV::showSettings() -{ - this->show(); -} - -void BigPictureTV::onCheckrateSpinBoxValueChanged() -{ - int newInterval = ui->checkrateSpinBox->value(); - windowCheckTimer->setInterval(newInterval); - saveSettings(); -} - -void BigPictureTV::onStartupCheckboxStateChanged() -{ - shortcutManager->manageShortcut(ui->startupCheckBox->isChecked()); -} - -void BigPictureTV::onDisableAudioCheckboxStateChanged(int state) -{ - bool isChecked = (state == Qt::Checked); - toggleAudioSettings(!isChecked); - saveSettings(); -} - -void BigPictureTV::onDisableMonitorCheckboxStateChanged(int state) -{ - bool isChecked = (state == Qt::Checked); - toggleMonitorSettings(!isChecked); - saveSettings(); -} + trayIconMenu = new QMenu(); + configAction = new QAction(tr("Settings"), this); + quitAction = new QAction(tr("Quit"), this); -void BigPictureTV::onTargetWindowComboBoxIndexChanged(int index) -{ - if (index == 1) { - toggleCustomWindowTitle(true); - } else { - toggleCustomWindowTitle(false); - } - saveSettings(); -} + connect(configAction, &QAction::triggered, this, &BigPictureTV::showSettings); + connect(quitAction, &QAction::triggered, this, &QApplication::quit); -void BigPictureTV::onAudioButtonClicked() -{ - ui->installAudioButton->setEnabled(false); - - QProcess process; - process.start( - "powershell", - QStringList() << "-NoProfile" << "-ExecutionPolicy" << "Bypass" << "-Command" - << "Install-PackageProvider -Name NuGet -Force -Scope CurrentUser; " - "Install-Module -Name AudioDeviceCmdlets -Force -Scope CurrentUser"); - - if (!process.waitForFinished()) { - QString status = tr("Error"); - QString message = tr("Failed to execute the PowerShell commands.\n" - "Please check if PowerShell is installed and properly configured."); - QMessageBox::critical(this, status, message); - } else { - QString output = process.readAllStandardOutput(); - QString errorOutput = process.readAllStandardError(); - int exitCode = process.exitCode(); - - QString status; - QString message; - - if (exitCode == 0) { - status = tr("Success"); - message = tr("AudioDeviceCmdlets module installed successfully.\nYou can now use audio " - "settings."); - QMessageBox::information(this, status, message); - } else { - status = tr("Error"); - message = tr("Failed to install NuGet package provider or AudioDeviceCmdlets module.\n" - "Please install them manually by running these commands in PowerShell:\n" - "Install-PackageProvider -Name NuGet -Force -Scope CurrentUser;\n" - "Install-Module -Name AudioDeviceCmdlets -Force -Scope CurrentUser\n" - "You should then restart the application.\n" - "Error details:\n") - + errorOutput; - QMessageBox::critical(this, status, message); - ui->installAudioButton->setEnabled(true); - } - } + trayIconMenu->addAction(configAction); + trayIconMenu->addAction(quitAction); + trayIcon->setContextMenu(trayIconMenu); - getAudioCapabilities(); + trayIcon->setToolTip("BigPictureTV"); + trayIcon->show(); } void BigPictureTV::checkWindowTitle() { - if (ui->targetWindowComboBox->currentIndex() == 1) { - if (ui->customWindowLineEdit->text().isEmpty() || ui->customWindowLineEdit->hasFocus()) { + if (settings.value("target_window").toInt() == 1) { + if (settings.value("custom_window").toString() != "") { return; } } @@ -235,13 +69,13 @@ void BigPictureTV::checkWindowTitle() return; } - bool disableVideo = ui->disableMonitorCheckBox->isChecked(); - bool disableAudio = ui->disableAudioCheckBox->isChecked(); + bool disableVideo = settings.value("disable_monitor").toBool(); + bool disableAudio = settings.value("disable_audio_switch").toBool(); bool isRunning; - if (ui->targetWindowComboBox->currentIndex() == 0) { + if (settings.value("target_window").toInt() == 0) { isRunning = steamWindowManager->isBigPictureRunning(); - } else if (ui->targetWindowComboBox->currentIndex() == 1) { - isRunning = steamWindowManager->isCustomWindowRunning(ui->customWindowLineEdit->text()); + } else if (settings.value("target_window").toInt() == 1) { + isRunning = steamWindowManager->isCustomWindowRunning(settings.value("custom_window").toString()); } if (isRunning && !gamemodeActive) { @@ -262,8 +96,8 @@ void BigPictureTV::handleMonitorChanges(bool isDesktopMode, bool disableVideo) if (disableVideo) return; - int index = isDesktopMode ? ui->desktopMonitorComboBox->currentIndex() - : ui->gamemodeMonitorComboBox->currentIndex(); + int index = isDesktopMode ? settings.value("desktop_monitor").toInt() + : settings.value("gamemode_monitor").toInt(); const char *command = nullptr; @@ -283,28 +117,30 @@ void BigPictureTV::handleAudioChanges(bool isDesktopMode, bool disableAudio) if (disableAudio) return; - std::string audioDevice = isDesktopMode ? ui->desktopAudioLineEdit->text().toStdString() - : ui->gamemodeAudioLineEdit->text().toStdString(); + QString audioDevice = isDesktopMode ? settings.value("desktop_audio").toString() + : settings.value("gamemode_audio").toString(); - try { - audioManager->setAudioDevice(audioDevice); - } catch (const std::runtime_error &e) { - std::cerr << "Error: " << e.what() << std::endl; - } + audioManager->setAudioDevice(audioDevice.toStdString()); + + //try { + // audioManager->setAudioDevice(audioDevice.toStdString()); + //} catch (const std::runtime_error &e) { + // //std::cerr << "Error: " << e.what() << std::endl; + //} } void BigPictureTV::handleActions(bool isDesktopMode) { - if (ui->closeDiscordCheckBox->isChecked()) { + if (settings.value("close_discord_action").toBool()) { handleDiscordAction(isDesktopMode); } - if (ui->enablePerformancePowerPlan->isChecked()) { + if (settings.value("disable_nightlight").toBool()) { handleNightLightAction(isDesktopMode); } - if (ui->disableNightLightCheckBox->isChecked()) { + if (settings.value("gamemode_powerplan").toBool()) { handlePowerPlanAction(isDesktopMode); } - if (ui->pauseMediaAction->isChecked()) { + if (settings.value("gamemode_pause_media").toBool()) { handleMediaAction(isDesktopMode); } } @@ -354,23 +190,6 @@ void BigPictureTV::handlePowerPlanAction(bool isDesktopMode) } } -void BigPictureTV::createDefaultSettings() -{ - firstRun = true; - ui->desktopAudioLineEdit->setText("Headset"); - ui->gamemodeAudioLineEdit->setText("TV"); - ui->desktopMonitorComboBox->setCurrentIndex(0); - ui->gamemodeMonitorComboBox->setCurrentIndex(0); - ui->closeDiscordCheckBox->setChecked(false); - ui->enablePerformancePowerPlan->setChecked(false); - ui->startupCheckBox->setChecked(false); - ui->disableAudioCheckBox->setChecked(false); - ui->disableMonitorCheckBox->setChecked(false); - ui->checkrateSpinBox->setValue(1000); - ui->disableNightLightCheckBox->setChecked(false); - saveSettings(); -} - void BigPictureTV::loadSettings() { QDir settingsDir(QFileInfo(settingsFile).absolutePath()); @@ -380,7 +199,7 @@ void BigPictureTV::loadSettings() QFile file(settingsFile); if (!file.exists()) { - createDefaultSettings(); + showSettings(); } else { if (file.open(QIODevice::ReadOnly)) { @@ -392,84 +211,17 @@ void BigPictureTV::loadSettings() file.close(); } } - applySettings(); -} - -void BigPictureTV::applySettings() -{ - ui->gamemodeAudioLineEdit->setText(settings.value("gamemode_audio").toString()); - ui->desktopAudioLineEdit->setText(settings.value("desktop_audio").toString()); - ui->disableAudioCheckBox->setChecked(settings.value("disable_audio_switch").toBool()); - ui->checkrateSpinBox->setValue(settings.value("checkrate").toInt(1000)); - ui->closeDiscordCheckBox->setChecked(settings.value("close_discord_action").toBool(false)); - ui->enablePerformancePowerPlan->setChecked(settings.value("gamemode_powerplan").toBool(false)); - ui->pauseMediaAction->setChecked(settings.value("gamemode_pause_media").toBool(false)); - ui->gamemodeMonitorComboBox->setCurrentIndex(settings.value("gamemode_monitor").toInt(0)); - ui->desktopMonitorComboBox->setCurrentIndex(settings.value("desktop_monitor").toInt(0)); - ui->disableMonitorCheckBox->setChecked(settings.value("disable_monitor_switch").toBool()); - ui->disableNightLightCheckBox->setChecked(settings.value("disable_nightlight").toBool()); - ui->targetWindowComboBox->setCurrentIndex(settings.value("target_window").toInt(0)); - ui->customWindowLineEdit->setText(settings.value("custom_window").toString()); - toggleAudioSettings(!ui->disableAudioCheckBox->isChecked()); - toggleMonitorSettings(!ui->disableMonitorCheckBox->isChecked()); - toggleCustomWindowTitle(ui->targetWindowComboBox->currentIndex() == 1); -} - -void BigPictureTV::saveSettings() -{ - settings["gamemode_audio"] = ui->gamemodeAudioLineEdit->text(); - settings["desktop_audio"] = ui->desktopAudioLineEdit->text(); - settings["disable_audio_switch"] = ui->disableAudioCheckBox->isChecked(); - settings["checkrate"] = ui->checkrateSpinBox->value(); - settings["close_discord_action"] = ui->closeDiscordCheckBox->isChecked(); - settings["gamemode_powerplan"] = ui->enablePerformancePowerPlan->isChecked(); - settings["gamemode_pause_media"] = ui->pauseMediaAction->isChecked(); - settings["gamemode_monitor"] = ui->gamemodeMonitorComboBox->currentIndex(); - settings["desktop_monitor"] = ui->desktopMonitorComboBox->currentIndex(); - settings["disable_monitor_switch"] = ui->disableMonitorCheckBox->isChecked(); - settings["disable_nightlight"] = ui->disableNightLightCheckBox->isChecked(); - settings["target_window"] = ui->targetWindowComboBox->currentIndex(); - settings["custom_window"] = ui->customWindowLineEdit->text(); - - QFile file(settingsFile); - if (file.open(QIODevice::WriteOnly)) { - QJsonDocument doc(settings); - file.write(doc.toJson(QJsonDocument::Indented)); - file.close(); - } -} - -void BigPictureTV::toggleAudioSettings(bool state) -{ - ui->desktopAudioLineEdit->setEnabled(state); - ui->desktopAudioLabel->setEnabled(state); - ui->gamemodeAudioLineEdit->setEnabled(state); - ui->gamemodeAudioLabel->setEnabled(state); } -void BigPictureTV::toggleMonitorSettings(bool state) -{ - ui->desktopMonitorComboBox->setEnabled(state); - ui->desktopMonitorLabel->setEnabled(state); - ui->gamemodeMonitorComboBox->setEnabled(state); - ui->gamemodeMonitorLabel->setEnabled(state); -} - -void BigPictureTV::toggleCustomWindowTitle(bool state) +void BigPictureTV::showSettings() { - ui->customWindowLineEdit->setEnabled(state); - ui->customWindowLabel->setEnabled(state); + configurator = new Configurator; + configurator->setAttribute(Qt::WA_DeleteOnClose); + connect(configurator, &Configurator::closed, this, &BigPictureTV::onConfiguratorClosed); + configurator->show(); } -void BigPictureTV::setupInfoTab() +void BigPictureTV::onConfiguratorClosed() { - ui->detectedSteamLanguage->setText(steamWindowManager->getSteamLanguage()); - - ui->targetWindowTitle->setText(steamWindowManager->getBigPictureWindowTitle()); - ui->repository->setText("github.com/Odizinne/BigPictureTV"); - ui->repository->setTextFormat(Qt::RichText); - ui->repository->setTextInteractionFlags(Qt::TextBrowserInteraction); - ui->repository->setOpenExternalLinks(true); - ui->commitID->setText(GIT_COMMIT_ID); - ui->commitDate->setText(GIT_COMMIT_DATE); + loadSettings(); } diff --git a/src/BigPictureTV/bigpicturetv.h b/src/BigPictureTV/bigpicturetv.h index dac1009..d20c8a6 100644 --- a/src/BigPictureTV/bigpicturetv.h +++ b/src/BigPictureTV/bigpicturetv.h @@ -1,93 +1,60 @@ #ifndef BIGPICTURETV_H #define BIGPICTURETV_H +#include +#include #include -#include -#include -#include -#include -#include -#include #include -#include -#include -#include -#include -#include -#include -#include -#include "NightLightSwitcher.h" -#include "steamwindowmanager.h" -#include "shortcutmanager.h" #include "utils.h" +#include "steamwindowmanager.h" #include "audiomanager.h" +#include "NightLightSwitcher.h" +#include "configurator.h" -namespace Ui { -class BigPictureTV; -} - -class BigPictureTV : public QMainWindow +class BigPictureTV : public QObject { Q_OBJECT public: - explicit BigPictureTV(QWidget *parent = nullptr); + explicit BigPictureTV(QObject *parent = nullptr); ~BigPictureTV(); - void createDefaultSettings(); - void loadSettings(); - void saveSettings(); - void applySettings(); private slots: - void onStartupCheckboxStateChanged(); - void onDisableAudioCheckboxStateChanged(int state); - void onDisableMonitorCheckboxStateChanged(int state); - void onTargetWindowComboBoxIndexChanged(int index); - void onAudioButtonClicked(); - void checkWindowTitle(); - void onCheckrateSpinBoxValueChanged(); - void showSettings(); + void onActionTriggered(); + void onConfiguratorClosed(); private: - QSystemTrayIcon *trayIcon; - void createTrayIcon(); - void initDiscordAction(); - QMenu *createMenu(); - bool gamemodeActive; - NightLightSwitcher* nightLightSwitcher; - AudioManager* audioManager; - SteamWindowManager* steamWindowManager; - ShortcutManager* shortcutManager; Utils* utils; - bool discordInstalled; - bool firstRun; + SteamWindowManager* steamWindowManager; + AudioManager* audioManager; + NightLightSwitcher* nightLightSwitcher; + Configurator* configurator; + QString activePowerPlan; bool nightLightState; bool discordState; - void getAudioCapabilities(); - void setCustomFusion(); - void populateComboboxes(); - void toggleAudioSettings(bool state); - void toggleMonitorSettings(bool state); - void toggleCustomWindowTitle(bool state); - void setupConnections(); - void handleMonitorChanges(bool isDesktopMode, bool disableVideo); - void handleAudioChanges(bool isDesktopMode, bool disableAudio); - void handleActions(bool isDesktopMode); - void handleDiscordAction(bool isDesktopMode); - void handleNightLightAction(bool isDesktopMode); - void handlePowerPlanAction(bool isDesktopMode); - void handleMediaAction(bool isDesktopMode); - void setupInfoTab(); - Ui::BigPictureTV *ui; + QSystemTrayIcon *trayIcon; QTimer *windowCheckTimer; - std::wstring shortcutName = L"BigPictureTV.lnk"; - QString settingsFilePath; + QMenu *trayIconMenu; + QAction *quitAction; + QAction *configAction; + void loadSettings(); + void createTrayIcon(); + void handleMediaAction(bool isDesktopMode); + void handlePowerPlanAction(bool isDesktopMode); + void handleNightLightAction(bool isDesktopMode); + void handleDiscordAction(bool isDesktopMode); + void handleActions(bool isDesktopMode); + void handleAudioChanges(bool isDesktopMode, bool disableAudio); + void handleMonitorChanges(bool isDesktopMode, bool disableVideo); + void checkWindowTitle(); + void showSettings(); + + bool gamemodeActive; QJsonObject settings; static const QString settingsFile; - QString status; - QString message; + }; #endif // BIGPICTURETV_H diff --git a/src/Configurator/configurator.cpp b/src/Configurator/configurator.cpp new file mode 100644 index 0000000..bda43e0 --- /dev/null +++ b/src/Configurator/configurator.cpp @@ -0,0 +1,284 @@ +#include "configurator.h" +#include "qdir.h" +#include "ui_configurator.h" +#include +#include +#include +#include +#include + +const QString Configurator::settingsFile = QStandardPaths::writableLocation( + QStandardPaths::AppDataLocation) + + "/BigPictureTV/settings.json"; + +Configurator::Configurator(QWidget *parent) + : QMainWindow(parent) + , utils(new Utils()) + , shortcutManager(new ShortcutManager()) + , steamWindowManager(new SteamWindowManager()) + , ui(new Ui::Configurator) +{ + ui->setupUi(this); + setWindowIcon(utils->getIconForTheme()); + setupInfoTab(); + populateComboboxes(); + loadSettings(); + setupConnections(); + getAudioCapabilities(); +} + +Configurator::~Configurator() +{ + saveSettings(); + emit closed(); + delete shortcutManager; + delete utils; + delete steamWindowManager; + delete ui; +} + +void Configurator::setupConnections() +{ + connect(ui->startupCheckBox, &QCheckBox::stateChanged, this, &Configurator::onStartupCheckboxStateChanged); + connect(ui->disableAudioCheckBox, &QCheckBox::checkStateChanged, this, &Configurator::onDisableAudioCheckboxStateChanged); + connect(ui->disableMonitorCheckBox, &QCheckBox::stateChanged, this, &Configurator::onDisableMonitorCheckboxStateChanged); + connect(ui->installAudioButton, &QPushButton::clicked, this, &Configurator::onAudioButtonClicked); + connect(ui->targetWindowComboBox, &QComboBox::currentIndexChanged, this, &Configurator::onTargetWindowComboBoxIndexChanged); + connect(ui->resetSettingsButton, &QPushButton::clicked, this, &Configurator::createDefaultSettings); + connect(ui->openSettingsButton, &QPushButton::clicked, this, []() { + QString settingsFolder = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation); + QDesktopServices::openUrl(QUrl::fromLocalFile(settingsFolder)); + }); + + ui->startupCheckBox->setChecked(shortcutManager->isShortcutPresent()); + initDiscordAction(); +} + +void Configurator::initDiscordAction() +{ + if (!utils->isDiscordInstalled()) { + ui->closeDiscordCheckBox->setChecked(false); + ui->closeDiscordCheckBox->setEnabled(false); + ui->CloseDiscordLabel->setEnabled(false); + ui->closeDiscordCheckBox->setToolTip(tr("Discord does not appear to be installed")); + ui->CloseDiscordLabel->setToolTip(tr("Discord does not appear to be installed")); + } +} + +void Configurator::getAudioCapabilities() +{ + if (!utils->isAudioDeviceCmdletsInstalled()) { + ui->disableAudioCheckBox->setChecked(true); + ui->disableAudioCheckBox->setEnabled(false); + toggleAudioSettings(false); + } else { + ui->disableAudioCheckBox->setEnabled(true); + ui->installAudioButton->setEnabled(false); + ui->installAudioButton->setText(tr("Audio module installed")); + if (!ui->disableAudioCheckBox->isChecked()) { + toggleAudioSettings(true); + } + } +} + +void Configurator::populateComboboxes() +{ + ui->desktopMonitorComboBox->addItem(tr("Internal")); + ui->desktopMonitorComboBox->addItem(tr("Extend")); + ui->gamemodeMonitorComboBox->addItem(tr("External")); + ui->gamemodeMonitorComboBox->addItem(tr("Clone")); + + ui->targetWindowComboBox->addItem(tr("Big Picture")); + ui->targetWindowComboBox->addItem(tr("Custom")); +} + +void Configurator::onStartupCheckboxStateChanged() +{ + shortcutManager->manageShortcut(ui->startupCheckBox->isChecked()); +} + +void Configurator::onDisableAudioCheckboxStateChanged(int state) +{ + bool isChecked = (state == Qt::Checked); + toggleAudioSettings(!isChecked); +} + +void Configurator::onDisableMonitorCheckboxStateChanged(int state) +{ + bool isChecked = (state == Qt::Checked); + toggleMonitorSettings(!isChecked); +} + +void Configurator::onTargetWindowComboBoxIndexChanged(int index) +{ + if (index == 1) { + toggleCustomWindowTitle(true); + } else { + toggleCustomWindowTitle(false); + } +} + +void Configurator::onAudioButtonClicked() +{ + ui->installAudioButton->setEnabled(false); + + QProcess process; + process.start( + "powershell", + QStringList() << "-NoProfile" << "-ExecutionPolicy" << "Bypass" << "-Command" + << "Install-PackageProvider -Name NuGet -Force -Scope CurrentUser; " + "Install-Module -Name AudioDeviceCmdlets -Force -Scope CurrentUser"); + + if (!process.waitForFinished()) { + QString status = tr("Error"); + QString message = tr("Failed to execute the PowerShell commands.\n" + "Please check if PowerShell is installed and properly configured."); + QMessageBox::critical(this, status, message); + } else { + QString output = process.readAllStandardOutput(); + QString errorOutput = process.readAllStandardError(); + int exitCode = process.exitCode(); + + QString status; + QString message; + + if (exitCode == 0) { + status = tr("Success"); + message = tr("AudioDeviceCmdlets module installed successfully.\nYou can now use audio " + "settings."); + QMessageBox::information(this, status, message); + } else { + status = tr("Error"); + message = tr("Failed to install NuGet package provider or AudioDeviceCmdlets module.\n" + "Please install them manually by running these commands in PowerShell:\n" + "Install-PackageProvider -Name NuGet -Force -Scope CurrentUser;\n" + "Install-Module -Name AudioDeviceCmdlets -Force -Scope CurrentUser\n" + "You should then restart the application.\n" + "Error details:\n") + + errorOutput; + QMessageBox::critical(this, status, message); + ui->installAudioButton->setEnabled(true); + } + } + + getAudioCapabilities(); +} + +void Configurator::createDefaultSettings() +{ + ui->desktopAudioLineEdit->setText("Headset"); + ui->gamemodeAudioLineEdit->setText("TV"); + ui->desktopMonitorComboBox->setCurrentIndex(0); + ui->gamemodeMonitorComboBox->setCurrentIndex(0); + ui->closeDiscordCheckBox->setChecked(false); + ui->enablePerformancePowerPlan->setChecked(false); + ui->startupCheckBox->setChecked(false); + ui->disableAudioCheckBox->setChecked(false); + ui->disableMonitorCheckBox->setChecked(false); + ui->checkrateSpinBox->setValue(1000); + ui->disableNightLightCheckBox->setChecked(false); + saveSettings(); +} + +void Configurator::loadSettings() +{ + QDir settingsDir(QFileInfo(settingsFile).absolutePath()); + if (!settingsDir.exists()) { + settingsDir.mkpath(settingsDir.absolutePath()); + } + + QFile file(settingsFile); + if (!file.exists()) { + createDefaultSettings(); + + } else { + if (file.open(QIODevice::ReadOnly)) { + QJsonParseError parseError; + QJsonDocument doc = QJsonDocument::fromJson(file.readAll(), &parseError); + if (parseError.error == QJsonParseError::NoError) { + settings = doc.object(); + } + file.close(); + } + } + applySettings(); +} + +void Configurator::applySettings() +{ + ui->gamemodeAudioLineEdit->setText(settings.value("gamemode_audio").toString()); + ui->desktopAudioLineEdit->setText(settings.value("desktop_audio").toString()); + ui->disableAudioCheckBox->setChecked(settings.value("disable_audio_switch").toBool()); + ui->checkrateSpinBox->setValue(settings.value("checkrate").toInt(1000)); + ui->closeDiscordCheckBox->setChecked(settings.value("close_discord_action").toBool(false)); + ui->enablePerformancePowerPlan->setChecked(settings.value("gamemode_powerplan").toBool(false)); + ui->pauseMediaAction->setChecked(settings.value("gamemode_pause_media").toBool(false)); + ui->gamemodeMonitorComboBox->setCurrentIndex(settings.value("gamemode_monitor").toInt(0)); + ui->desktopMonitorComboBox->setCurrentIndex(settings.value("desktop_monitor").toInt(0)); + ui->disableMonitorCheckBox->setChecked(settings.value("disable_monitor_switch").toBool()); + ui->disableNightLightCheckBox->setChecked(settings.value("disable_nightlight").toBool()); + ui->targetWindowComboBox->setCurrentIndex(settings.value("target_window").toInt(0)); + ui->customWindowLineEdit->setText(settings.value("custom_window").toString()); + toggleAudioSettings(!ui->disableAudioCheckBox->isChecked()); + toggleMonitorSettings(!ui->disableMonitorCheckBox->isChecked()); + toggleCustomWindowTitle(ui->targetWindowComboBox->currentIndex() == 1); +} + +void Configurator::saveSettings() +{ + settings["gamemode_audio"] = ui->gamemodeAudioLineEdit->text(); + settings["desktop_audio"] = ui->desktopAudioLineEdit->text(); + settings["disable_audio_switch"] = ui->disableAudioCheckBox->isChecked(); + settings["checkrate"] = ui->checkrateSpinBox->value(); + settings["close_discord_action"] = ui->closeDiscordCheckBox->isChecked(); + settings["gamemode_powerplan"] = ui->enablePerformancePowerPlan->isChecked(); + settings["gamemode_pause_media"] = ui->pauseMediaAction->isChecked(); + settings["gamemode_monitor"] = ui->gamemodeMonitorComboBox->currentIndex(); + settings["desktop_monitor"] = ui->desktopMonitorComboBox->currentIndex(); + settings["disable_monitor_switch"] = ui->disableMonitorCheckBox->isChecked(); + settings["disable_nightlight"] = ui->disableNightLightCheckBox->isChecked(); + settings["target_window"] = ui->targetWindowComboBox->currentIndex(); + settings["custom_window"] = ui->customWindowLineEdit->text(); + + QFile file(settingsFile); + if (file.open(QIODevice::WriteOnly)) { + QJsonDocument doc(settings); + file.write(doc.toJson(QJsonDocument::Indented)); + file.close(); + } +} + +void Configurator::toggleAudioSettings(bool state) +{ + ui->desktopAudioLineEdit->setEnabled(state); + ui->desktopAudioLabel->setEnabled(state); + ui->gamemodeAudioLineEdit->setEnabled(state); + ui->gamemodeAudioLabel->setEnabled(state); +} + +void Configurator::toggleMonitorSettings(bool state) +{ + ui->desktopMonitorComboBox->setEnabled(state); + ui->desktopMonitorLabel->setEnabled(state); + ui->gamemodeMonitorComboBox->setEnabled(state); + ui->gamemodeMonitorLabel->setEnabled(state); +} + +void Configurator::toggleCustomWindowTitle(bool state) +{ + ui->customWindowLineEdit->setEnabled(state); + ui->customWindowLabel->setEnabled(state); +} + +void Configurator::setupInfoTab() +{ + ui->detectedSteamLanguage->setText(steamWindowManager->getSteamLanguage()); + + ui->targetWindowTitle->setText(steamWindowManager->getBigPictureWindowTitle()); + ui->repository->setText("github.com/Odizinne/BigPictureTV"); + ui->repository->setTextFormat(Qt::RichText); + ui->repository->setTextInteractionFlags(Qt::TextBrowserInteraction); + ui->repository->setOpenExternalLinks(true); + ui->commitID->setText(GIT_COMMIT_ID); + ui->commitDate->setText(GIT_COMMIT_DATE); +} diff --git a/src/Configurator/configurator.h b/src/Configurator/configurator.h new file mode 100644 index 0000000..2c131be --- /dev/null +++ b/src/Configurator/configurator.h @@ -0,0 +1,65 @@ +#ifndef CONFIGURATOR_H +#define CONFIGURATOR_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "shortcutmanager.h" +#include "utils.h" +#include "steamwindowmanager.h" + +namespace Ui { +class Configurator; +} + +class Configurator : public QMainWindow +{ + Q_OBJECT + +public: + explicit Configurator(QWidget *parent = nullptr); + ~Configurator(); + + +private slots: + void onStartupCheckboxStateChanged(); + void onDisableAudioCheckboxStateChanged(int state); + void onDisableMonitorCheckboxStateChanged(int state); + void onTargetWindowComboBoxIndexChanged(int index); + void onAudioButtonClicked(); + +private: + void initDiscordAction(); + Utils* utils; + ShortcutManager* shortcutManager; + SteamWindowManager* steamWindowManager; + bool discordInstalled; + void getAudioCapabilities(); + void populateComboboxes(); + void toggleAudioSettings(bool state); + void toggleMonitorSettings(bool state); + void toggleCustomWindowTitle(bool state); + void setupConnections(); + void setupInfoTab(); + void createDefaultSettings(); + void loadSettings(); + void saveSettings(); + void applySettings(); + + Ui::Configurator *ui; + std::wstring shortcutName = L"BigPictureTV.lnk"; + QString settingsFilePath; + QJsonObject settings; + static const QString settingsFile; + +signals: + void closed(); +}; + +#endif // CONFIGURATOR_H diff --git a/src/BigPictureTV/bigpicturetv.ui b/src/Configurator/configurator.ui similarity index 99% rename from src/BigPictureTV/bigpicturetv.ui rename to src/Configurator/configurator.ui index bf69044..e4cecbf 100644 --- a/src/BigPictureTV/bigpicturetv.ui +++ b/src/Configurator/configurator.ui @@ -1,7 +1,7 @@ - BigPictureTV - + Configurator + 0