File indexing completed on 2025-01-05 04:29:55
0001 /** 0002 * SPDX-FileCopyrightText: 2023 Bart De Vries <bart@mogwai.be> 0003 * 0004 * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 0005 */ 0006 0007 #include "systrayicon.h" 0008 0009 #ifndef Q_OS_ANDROID 0010 #include <QCoreApplication> 0011 #include <QFile> 0012 #include <QMenu> 0013 0014 #include <KLocalizedString> 0015 0016 #include "audiomanager.h" 0017 #include "kmediasession.h" 0018 #include "settingsmanager.h" 0019 0020 SystrayIcon::SystrayIcon(QObject *parent) 0021 : QSystemTrayIcon(parent) 0022 { 0023 setIconColor(intToIconColorEnum(SettingsManager::self()->trayIconType())); 0024 setToolTip(i18nc("@info:tooltip", 0025 "Kasts\n" 0026 "Middle-click to play/pause")); 0027 0028 QMenu *menu = new QMenu(); 0029 0030 connect(this, &QSystemTrayIcon::activated, this, [this](QSystemTrayIcon::ActivationReason reason) { 0031 if (reason == QSystemTrayIcon::Trigger) { 0032 Q_EMIT raiseWindow(); 0033 } else if (reason == QSystemTrayIcon::MiddleClick) { 0034 AudioManager::instance().playPause(); 0035 } 0036 }); 0037 0038 connect(SettingsManager::self(), &SettingsManager::showTrayIconChanged, this, [this]() { 0039 if (SettingsManager::self()->showTrayIcon()) { 0040 show(); 0041 } else { 0042 hide(); 0043 } 0044 }); 0045 0046 connect(SettingsManager::self(), &SettingsManager::trayIconTypeChanged, this, [this]() { 0047 setIconColor(intToIconColorEnum(SettingsManager::self()->trayIconType())); 0048 }); 0049 0050 // Seek backward 0051 QAction *skipBackwardAction = new QAction(i18nc("@action:inmenu", "Seek Backward"), this); 0052 skipBackwardAction->setIcon(QIcon::fromTheme(QStringLiteral("media-seek-backward"))); 0053 skipBackwardAction->setEnabled(AudioManager::instance().canSkipBackward()); 0054 0055 connect(skipBackwardAction, &QAction::triggered, &AudioManager::instance(), &AudioManager::skipBackward); 0056 menu->addAction(skipBackwardAction); 0057 0058 connect(&AudioManager::instance(), &AudioManager::canSkipBackwardChanged, this, [skipBackwardAction]() { 0059 skipBackwardAction->setEnabled(AudioManager::instance().canSkipBackward()); 0060 }); 0061 0062 // Play / Pause 0063 QAction *playAction = new QAction(i18nc("@action:inmenu", "Play"), this); 0064 playAction->setIcon(QIcon::fromTheme(QStringLiteral("media-playback-start"))); 0065 playAction->setVisible(AudioManager::instance().playbackState() != KMediaSession::PlaybackState::PlayingState); 0066 playAction->setEnabled(AudioManager::instance().canPlay()); 0067 0068 connect(playAction, &QAction::triggered, &AudioManager::instance(), &AudioManager::play); 0069 menu->addAction(playAction); 0070 0071 QAction *pauseAction = new QAction(i18nc("@action:inmenu", "Pause"), this); 0072 pauseAction->setIcon(QIcon::fromTheme(QStringLiteral("media-playback-pause"))); 0073 pauseAction->setVisible(AudioManager::instance().playbackState() == KMediaSession::PlaybackState::PlayingState); 0074 pauseAction->setEnabled(AudioManager::instance().canPlay()); 0075 0076 connect(pauseAction, &QAction::triggered, &AudioManager::instance(), &AudioManager::pause); 0077 menu->addAction(pauseAction); 0078 0079 connect(&AudioManager::instance(), &AudioManager::playbackStateChanged, this, [playAction, pauseAction](KMediaSession::PlaybackState state) { 0080 playAction->setVisible(state != KMediaSession::PlaybackState::PlayingState); 0081 pauseAction->setVisible(state == KMediaSession::PlaybackState::PlayingState); 0082 }); 0083 0084 connect(&AudioManager::instance(), &AudioManager::canPlayChanged, this, [playAction, pauseAction]() { 0085 playAction->setEnabled(AudioManager::instance().canPlay()); 0086 pauseAction->setEnabled(AudioManager::instance().canPlay()); 0087 }); 0088 0089 // Seek forward 0090 QAction *skipForwardAction = new QAction(i18nc("@action:inmenu", "Seek Forward"), this); 0091 skipForwardAction->setIcon(QIcon::fromTheme(QStringLiteral("media-seek-forward"))); 0092 skipForwardAction->setEnabled(AudioManager::instance().canSkipForward()); 0093 0094 connect(skipForwardAction, &QAction::triggered, &AudioManager::instance(), &AudioManager::skipForward); 0095 menu->addAction(skipForwardAction); 0096 0097 connect(&AudioManager::instance(), &AudioManager::canSkipForwardChanged, this, [skipForwardAction]() { 0098 skipForwardAction->setEnabled(AudioManager::instance().canSkipForward()); 0099 }); 0100 0101 // Skip forward 0102 QAction *nextAction = new QAction(i18nc("@action:inmenu", "Skip Forward"), this); 0103 nextAction->setIcon(QIcon::fromTheme(QStringLiteral("media-skip-forward"))); 0104 nextAction->setEnabled(AudioManager::instance().canGoNext()); 0105 0106 connect(nextAction, &QAction::triggered, &AudioManager::instance(), &AudioManager::next); 0107 menu->addAction(nextAction); 0108 0109 connect(&AudioManager::instance(), &AudioManager::canGoNextChanged, this, [nextAction]() { 0110 nextAction->setEnabled(AudioManager::instance().canGoNext()); 0111 }); 0112 0113 // Separator 0114 menu->addSeparator(); 0115 0116 // Quit 0117 QAction *quitAction = new QAction(i18nc("@action:inmenu", "Quit"), this); 0118 quitAction->setIcon(QIcon::fromTheme(QStringLiteral("application-exit"))); 0119 0120 connect(quitAction, &QAction::triggered, QCoreApplication::instance(), QCoreApplication::quit); 0121 menu->addAction(quitAction); 0122 0123 setContextMenu(menu); 0124 0125 if (SettingsManager::self()->showTrayIcon()) { 0126 show(); 0127 } 0128 } 0129 #else 0130 SystrayIcon::SystrayIcon(QObject *parent) 0131 : QObject(parent) 0132 { 0133 } 0134 #endif 0135 0136 bool SystrayIcon::available() const 0137 { 0138 #ifndef Q_OS_ANDROID 0139 return QSystemTrayIcon::isSystemTrayAvailable(); 0140 #else 0141 return false; 0142 #endif 0143 } 0144 0145 void SystrayIcon::setIconColor(SystrayIcon::IconColor iconColor) 0146 { 0147 #ifndef Q_OS_ANDROID 0148 // do not specify svg-extension; icon will not be visible due to [QTBUG-53550] 0149 switch (iconColor) { 0150 case SystrayIcon::IconColor::Colorful: 0151 setIcon(QIcon(QStringLiteral(":/icons/kasts"))); 0152 break; 0153 case SystrayIcon::IconColor::Light: 0154 setIcon(QIcon(QStringLiteral(":/icons/kasts-tray-light"))); 0155 break; 0156 case SystrayIcon::IconColor::Dark: 0157 setIcon(QIcon(QStringLiteral(":/icons/kasts-tray-dark"))); 0158 break; 0159 } 0160 #endif 0161 } 0162 0163 int SystrayIcon::iconColorEnumToInt(SystrayIcon::IconColor iconColor) 0164 { 0165 switch (iconColor) { 0166 case SystrayIcon::IconColor::Light: 0167 return 1; 0168 case SystrayIcon::IconColor::Dark: 0169 return 2; 0170 case SystrayIcon::IconColor::Colorful: 0171 default: 0172 return 0; 0173 } 0174 } 0175 0176 SystrayIcon::IconColor SystrayIcon::intToIconColorEnum(int iconColorCode) 0177 { 0178 switch (iconColorCode) { 0179 case 1: 0180 return SystrayIcon::IconColor::Light; 0181 case 2: 0182 return SystrayIcon::IconColor::Dark; 0183 case 0: 0184 default: 0185 return SystrayIcon::IconColor::Colorful; 0186 } 0187 }