File indexing completed on 2024-05-12 16:21:31

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 
0025     QMenu *menu = new QMenu();
0026 
0027     connect(this, &QSystemTrayIcon::activated, this, [this](QSystemTrayIcon::ActivationReason reason) {
0028         if (reason == QSystemTrayIcon::Trigger) {
0029             Q_EMIT raiseWindow();
0030         }
0031     });
0032 
0033     connect(SettingsManager::self(), &SettingsManager::showTrayIconChanged, this, [this]() {
0034         if (SettingsManager::self()->showTrayIcon()) {
0035             show();
0036         } else {
0037             hide();
0038         }
0039     });
0040 
0041     connect(SettingsManager::self(), &SettingsManager::trayIconTypeChanged, this, [this]() {
0042         setIconColor(intToIconColorEnum(SettingsManager::self()->trayIconType()));
0043     });
0044 
0045     // Seek backward
0046     QAction *skipBackwardAction = new QAction(i18nc("@action:inmenu", "Seek Backward"), this);
0047     skipBackwardAction->setIcon(QIcon::fromTheme(QStringLiteral("media-seek-backward")));
0048     skipBackwardAction->setEnabled(AudioManager::instance().canSkipBackward());
0049 
0050     connect(skipBackwardAction, &QAction::triggered, &AudioManager::instance(), &AudioManager::skipBackward);
0051     menu->addAction(skipBackwardAction);
0052 
0053     connect(&AudioManager::instance(), &AudioManager::canSkipBackwardChanged, this, [skipBackwardAction]() {
0054         skipBackwardAction->setEnabled(AudioManager::instance().canSkipBackward());
0055     });
0056 
0057     // Play / Pause
0058     QAction *playAction = new QAction(i18nc("@action:inmenu", "Play"), this);
0059     playAction->setIcon(QIcon::fromTheme(QStringLiteral("media-playback-start")));
0060     playAction->setVisible(AudioManager::instance().playbackState() != KMediaSession::PlaybackState::PlayingState);
0061     playAction->setEnabled(AudioManager::instance().canPlay());
0062 
0063     connect(playAction, &QAction::triggered, &AudioManager::instance(), &AudioManager::play);
0064     menu->addAction(playAction);
0065 
0066     QAction *pauseAction = new QAction(i18nc("@action:inmenu", "Pause"), this);
0067     pauseAction->setIcon(QIcon::fromTheme(QStringLiteral("media-playback-pause")));
0068     pauseAction->setVisible(AudioManager::instance().playbackState() == KMediaSession::PlaybackState::PlayingState);
0069     pauseAction->setEnabled(AudioManager::instance().canPlay());
0070 
0071     connect(pauseAction, &QAction::triggered, &AudioManager::instance(), &AudioManager::pause);
0072     menu->addAction(pauseAction);
0073 
0074     connect(&AudioManager::instance(), &AudioManager::playbackStateChanged, this, [playAction, pauseAction](KMediaSession::PlaybackState state) {
0075         playAction->setVisible(state != KMediaSession::PlaybackState::PlayingState);
0076         pauseAction->setVisible(state == KMediaSession::PlaybackState::PlayingState);
0077     });
0078 
0079     connect(&AudioManager::instance(), &AudioManager::canPlayChanged, this, [playAction, pauseAction]() {
0080         playAction->setEnabled(AudioManager::instance().canPlay());
0081         pauseAction->setEnabled(AudioManager::instance().canPlay());
0082     });
0083 
0084     // Seek forward
0085     QAction *skipForwardAction = new QAction(i18nc("@action:inmenu", "Seek Forward"), this);
0086     skipForwardAction->setIcon(QIcon::fromTheme(QStringLiteral("media-seek-forward")));
0087     skipForwardAction->setEnabled(AudioManager::instance().canSkipForward());
0088 
0089     connect(skipForwardAction, &QAction::triggered, &AudioManager::instance(), &AudioManager::skipForward);
0090     menu->addAction(skipForwardAction);
0091 
0092     connect(&AudioManager::instance(), &AudioManager::canSkipForwardChanged, this, [skipForwardAction]() {
0093         skipForwardAction->setEnabled(AudioManager::instance().canSkipForward());
0094     });
0095 
0096     // Skip forward
0097     QAction *nextAction = new QAction(i18nc("@action:inmenu", "Skip Forward"), this);
0098     nextAction->setIcon(QIcon::fromTheme(QStringLiteral("media-skip-forward")));
0099     nextAction->setEnabled(AudioManager::instance().canGoNext());
0100 
0101     connect(nextAction, &QAction::triggered, &AudioManager::instance(), &AudioManager::next);
0102     menu->addAction(nextAction);
0103 
0104     connect(&AudioManager::instance(), &AudioManager::canGoNextChanged, this, [nextAction]() {
0105         nextAction->setEnabled(AudioManager::instance().canGoNext());
0106     });
0107 
0108     // Separator
0109     menu->addSeparator();
0110 
0111     // Quit
0112     QAction *quitAction = new QAction(i18nc("@action:inmenu", "Quit"), this);
0113     quitAction->setIcon(QIcon::fromTheme(QStringLiteral("application-exit")));
0114 
0115     connect(quitAction, &QAction::triggered, QCoreApplication::instance(), QCoreApplication::quit);
0116     menu->addAction(quitAction);
0117 
0118     setContextMenu(menu);
0119 
0120     if (SettingsManager::self()->showTrayIcon()) {
0121         show();
0122     }
0123 }
0124 #else
0125 SystrayIcon::SystrayIcon(QObject *parent)
0126     : QObject(parent)
0127 {
0128 }
0129 #endif
0130 
0131 SystrayIcon::~SystrayIcon()
0132 {
0133 }
0134 
0135 bool SystrayIcon::available() const
0136 {
0137 #ifndef Q_OS_ANDROID
0138     return QSystemTrayIcon::isSystemTrayAvailable();
0139 #else
0140     return false;
0141 #endif
0142 }
0143 
0144 void SystrayIcon::setIconColor(SystrayIcon::IconColor iconColor)
0145 {
0146 #ifndef Q_OS_ANDROID
0147     // do not specify svg-extension; icon will not be visible due to [QTBUG-53550]
0148     switch (iconColor) {
0149     case SystrayIcon::IconColor::Colorful:
0150         setIcon(QIcon(QStringLiteral(":/logo")));
0151         break;
0152     case SystrayIcon::IconColor::Light:
0153         setIcon(QIcon(QStringLiteral(":/kasts-tray-light")));
0154         break;
0155     case SystrayIcon::IconColor::Dark:
0156         setIcon(QIcon(QStringLiteral(":/kasts-tray-dark")));
0157         break;
0158     }
0159 #endif
0160 }
0161 
0162 int SystrayIcon::iconColorEnumToInt(SystrayIcon::IconColor iconColor)
0163 {
0164     switch (iconColor) {
0165     case SystrayIcon::IconColor::Light:
0166         return 1;
0167     case SystrayIcon::IconColor::Dark:
0168         return 2;
0169     case SystrayIcon::IconColor::Colorful:
0170     default:
0171         return 0;
0172     }
0173 }
0174 
0175 SystrayIcon::IconColor SystrayIcon::intToIconColorEnum(int iconColorCode)
0176 {
0177     switch (iconColorCode) {
0178     case 1:
0179         return SystrayIcon::IconColor::Light;
0180     case 2:
0181         return SystrayIcon::IconColor::Dark;
0182     case 0:
0183     default:
0184         return SystrayIcon::IconColor::Colorful;
0185     }
0186 }