From 9cfa88dd8c8fa753878a424137b9ce960bfcf817 Mon Sep 17 00:00:00 2001 From: WarmUpTill Date: Tue, 2 May 2023 00:04:09 +0200 Subject: [PATCH] Add support setting title and icon of system tray message --- data/locale/de-DE.ini | 1 - data/locale/en-US.ini | 5 +- data/locale/es-ES.ini | 1 - data/locale/tr-TR.ini | 1 - data/locale/zh-CN.ini | 1 - src/macro-core/macro-action-systray.cpp | 88 +++++++++++++++++++------ src/macro-core/macro-action-systray.hpp | 15 ++++- src/utils/utility.cpp | 10 ++- src/utils/utility.hpp | 3 +- 9 files changed, 94 insertions(+), 31 deletions(-) diff --git a/data/locale/de-DE.ini b/data/locale/de-DE.ini index b3195275..170d7ce0 100644 --- a/data/locale/de-DE.ini +++ b/data/locale/de-DE.ini @@ -545,7 +545,6 @@ AdvSceneSwitcher.action.random="Zufall" AdvSceneSwitcher.action.random.allowRepeat="Aufeinanderfolgende Ausführung desselben Makros zulassen" AdvSceneSwitcher.action.random.entry="Zufällige Ausführung eines der folgenden Makros (pausierte Makros werden ignoriert)" AdvSceneSwitcher.action.systray="Benachrichtigung im System-Tray" -AdvSceneSwitcher.action.systray.entry="Benachrichtigung anzeigen: {{message}}" AdvSceneSwitcher.action.screenshot="Screenshot" AdvSceneSwitcher.action.screenshot.save.default="Standard" AdvSceneSwitcher.action.screenshot.save.custom="Benutzerdefiniert" diff --git a/data/locale/en-US.ini b/data/locale/en-US.ini index 7a47351f..76e55515 100644 --- a/data/locale/en-US.ini +++ b/data/locale/en-US.ini @@ -584,7 +584,10 @@ AdvSceneSwitcher.action.random="Random" AdvSceneSwitcher.action.random.allowRepeat="Allow consecutive execution of the same macro" AdvSceneSwitcher.action.random.entry="Randomly run any of the following macros (paused macros are ignored)" AdvSceneSwitcher.action.systray="System tray notification" -AdvSceneSwitcher.action.systray.entry="Show notification: {{message}}" +AdvSceneSwitcher.action.systray.title="Title:" +AdvSceneSwitcher.action.systray.message="Message:" +AdvSceneSwitcher.action.systray.icon="Icon:" +AdvSceneSwitcher.action.systray.iconHint="Leave blank to use the default icon" AdvSceneSwitcher.action.screenshot="Screenshot" AdvSceneSwitcher.action.screenshot.save.default="Default" AdvSceneSwitcher.action.screenshot.save.custom="Custom" diff --git a/data/locale/es-ES.ini b/data/locale/es-ES.ini index c338c245..6dbed907 100644 --- a/data/locale/es-ES.ini +++ b/data/locale/es-ES.ini @@ -460,7 +460,6 @@ AdvSceneSwitcher.action.timer.entry="{{timerAction}} temporizadores en {{macros} AdvSceneSwitcher.action.random="Aleatorio" AdvSceneSwitcher.action.random.entry="Ejecute aleatoriamente cualquiera de las siguientes macros (las macros en pausa se ignoran)" AdvSceneSwitcher.action.systray="Notificación de la bandeja del sistema" -AdvSceneSwitcher.action.systray.entry="Mostrar notificación: {{message}}" AdvSceneSwitcher.action.screenshot="Captura de pantalla" AdvSceneSwitcher.action.screenshot.mainOutput="Salida principal de OBS" AdvSceneSwitcher.action.profile="Perfil" diff --git a/data/locale/tr-TR.ini b/data/locale/tr-TR.ini index e281ff8b..9383c83d 100644 --- a/data/locale/tr-TR.ini +++ b/data/locale/tr-TR.ini @@ -377,7 +377,6 @@ AdvSceneSwitcher.action.timer.entry="{{timerAction}} zamanlayıcılar açık {{m AdvSceneSwitcher.action.random="Rastgele" AdvSceneSwitcher.action.random.entry="Aşağıdaki makrolardan herhangi birini rastgele çalıştırın (duraklatılmış makrolar yoksayılır)" AdvSceneSwitcher.action.systray="Sistem tepsisi bildirimi" -AdvSceneSwitcher.action.systray.entry="Bildirimleri göster: {{message}}" AdvSceneSwitcher.action.screenshot="Ekran görüntüsü" AdvSceneSwitcher.action.screenshot.mainOutput="OBS'nin ana çıkışı" AdvSceneSwitcher.action.profile="Profil" diff --git a/data/locale/zh-CN.ini b/data/locale/zh-CN.ini index 3eee24bd..3f458e78 100644 --- a/data/locale/zh-CN.ini +++ b/data/locale/zh-CN.ini @@ -505,7 +505,6 @@ AdvSceneSwitcher.action.timer.entry="{{timerAction}} 定时在 {{macros}} {{dura AdvSceneSwitcher.action.random="随机" AdvSceneSwitcher.action.random.entry="随机运行以下任何宏(忽略暂停的宏)" AdvSceneSwitcher.action.systray="系统托盘通知" -AdvSceneSwitcher.action.systray.entry="显示通知: {{message}}" AdvSceneSwitcher.action.screenshot="截图" AdvSceneSwitcher.action.screenshot.save.default="默认" AdvSceneSwitcher.action.screenshot.save.custom="其他" diff --git a/src/macro-core/macro-action-systray.cpp b/src/macro-core/macro-action-systray.cpp index fc4db92a..1c8be003 100644 --- a/src/macro-core/macro-action-systray.cpp +++ b/src/macro-core/macro-action-systray.cpp @@ -12,54 +12,102 @@ bool MacroActionSystray::_registered = MacroActionFactory::Register( bool MacroActionSystray::PerformAction() { - if (_msg.empty()) { - return true; + if (_lastPath != std::string(_iconPath)) { + _lastPath = _iconPath; + _icon = QIcon(QString::fromStdString(_iconPath)); } - DisplayTrayMessage(obs_module_text("AdvSceneSwitcher.pluginName"), - QString::fromStdString(_msg)); + DisplayTrayMessage(QString::fromStdString(_title), + QString::fromStdString(_message), _icon); return true; } void MacroActionSystray::LogAction() const { - vblog(LOG_INFO, "display systray message \"%s\"", _msg.c_str()); + vblog(LOG_INFO, "display systray message \"%s\":\n%s", _title.c_str(), + _message.c_str()); } bool MacroActionSystray::Save(obs_data_t *obj) const { MacroAction::Save(obj); - obs_data_set_string(obj, "message", _msg.c_str()); + _message.Save(obj, "message"); + _title.Save(obj, "title"); + _iconPath.Save(obj, "icon"); + obs_data_set_int(obj, "version", 1); return true; } bool MacroActionSystray::Load(obs_data_t *obj) { MacroAction::Load(obj); - _msg = obs_data_get_string(obj, "message"); + _message.Load(obj, "message"); + _title.Load(obj, "title"); + _iconPath.Load(obj, "icon"); + if (!obs_data_has_user_value(obj, "version")) { + _title = obs_module_text("AdvSceneSwitcher.pluginName"); + } return true; } MacroActionSystrayEdit::MacroActionSystrayEdit( QWidget *parent, std::shared_ptr entryData) - : QWidget(parent) + : QWidget(parent), + _message(new VariableLineEdit(this)), + _title(new VariableLineEdit(this)), + _iconPath(new FileSelection()) { - _msg = new QLineEdit(); - QWidget::connect(_msg, SIGNAL(editingFinished()), this, - SLOT(MessageChanged())); + _iconPath->setToolTip( + obs_module_text("AdvSceneSwitcher.action.systray.iconHint")); - QHBoxLayout *mainLayout = new QHBoxLayout; - std::unordered_map widgetPlaceholders = { - {"{{message}}", _msg}, - }; - PlaceWidgets(obs_module_text("AdvSceneSwitcher.action.systray.entry"), - mainLayout, widgetPlaceholders); - setLayout(mainLayout); + QWidget::connect(_message, SIGNAL(editingFinished()), this, + SLOT(MessageChanged())); + QWidget::connect(_title, SIGNAL(editingFinished()), this, + SLOT(TitleChanged())); + QWidget::connect(_iconPath, SIGNAL(PathChanged(const QString &)), this, + SLOT(IconPathChanged(const QString &))); + + auto layout = new QGridLayout(); + layout->addWidget(new QLabel(obs_module_text( + "AdvSceneSwitcher.action.systray.title")), + 0, 0); + layout->addWidget(_title, 0, 1); + layout->addWidget(new QLabel(obs_module_text( + "AdvSceneSwitcher.action.systray.message")), + 1, 0); + layout->addWidget(_message, 1, 1); + layout->addWidget(new QLabel(obs_module_text( + "AdvSceneSwitcher.action.systray.icon")), + 2, 0); + layout->addWidget(_iconPath, 2, 1); + setLayout(layout); _entryData = entryData; - _msg->setText(QString::fromStdString(_entryData->_msg)); + _message->setText(_entryData->_message); + _title->setText(_entryData->_title); + _iconPath->SetPath(_entryData->_iconPath); _loading = false; } +void MacroActionSystrayEdit::TitleChanged() +{ + if (_loading || !_entryData) { + return; + } + + auto lock = LockContext(); + _entryData->_title = _title->text().toStdString(); +} + +void MacroActionSystrayEdit::IconPathChanged(const QString &text) +{ + if (_loading || !_entryData) { + return; + } + + auto lock = LockContext(); + _entryData->_iconPath = text.toStdString(); +} + void MacroActionSystrayEdit::MessageChanged() { if (_loading || !_entryData) { @@ -67,7 +115,7 @@ void MacroActionSystrayEdit::MessageChanged() } auto lock = LockContext(); - _entryData->_msg = _msg->text().toStdString(); + _entryData->_message = _message->text().toStdString(); } } // namespace advss diff --git a/src/macro-core/macro-action-systray.hpp b/src/macro-core/macro-action-systray.hpp index d38d35aa..2608acd6 100644 --- a/src/macro-core/macro-action-systray.hpp +++ b/src/macro-core/macro-action-systray.hpp @@ -1,5 +1,7 @@ #pragma once #include "macro-action-edit.hpp" +#include "variable-string.hpp" +#include "file-selection.hpp" #include @@ -18,9 +20,14 @@ public: return std::make_shared(m); } - std::string _msg = ""; + StringVariable _message = ""; + StringVariable _title = obs_module_text("AdvSceneSwitcher.pluginName"); + StringVariable _iconPath = ""; private: + QIcon _icon; + std::string _lastPath; + static bool _registered; static const std::string id; }; @@ -42,12 +49,16 @@ public: private slots: void MessageChanged(); + void TitleChanged(); + void IconPathChanged(const QString &text); protected: std::shared_ptr _entryData; private: - QLineEdit *_msg; + VariableLineEdit *_message; + VariableLineEdit *_title; + FileSelection *_iconPath; bool _loading = true; }; diff --git a/src/utils/utility.cpp b/src/utils/utility.cpp index 88c73ec9..4ac9c1bb 100644 --- a/src/utils/utility.cpp +++ b/src/utils/utility.cpp @@ -466,15 +466,19 @@ bool DisplayMessage(const QString &msg, bool question) return false; } -void DisplayTrayMessage(const QString &title, const QString &msg) +void DisplayTrayMessage(const QString &title, const QString &msg, + const QIcon &icon) { auto tray = reinterpret_cast( obs_frontend_get_system_tray()); if (!tray) { return; } - - tray->showMessage(title, msg); + if (icon.isNull()) { + tray->showMessage(title, msg); + } else { + tray->showMessage(title, msg, icon); + } } void AddSelectionEntry(QComboBox *sel, const char *description, bool selectable, diff --git a/src/utils/utility.hpp b/src/utils/utility.hpp index 70313d71..d9a6bef4 100644 --- a/src/utils/utility.hpp +++ b/src/utils/utility.hpp @@ -100,7 +100,8 @@ int FindIdxInRagne(QComboBox *list, int start, int stop, /* UI helpers */ bool DisplayMessage(const QString &msg, bool question = false); -void DisplayTrayMessage(const QString &title, const QString &msg); +void DisplayTrayMessage(const QString &title, const QString &msg, + const QIcon &icon = QIcon()); bool WindowPosValid(QPoint pos); std::string GetThemeTypeName();