kde-workspace/plasma/applets/systemtray/protocols/dbussystemtray/dbussystemtraytask.cpp
Ivailo Monev dc50956578 plasma: remove bogus status notifier item animation feature
AttentionMovieName is not valid property of the org.kde.StatusNotifierItem
interface, see:
kdelibs/kdeui/notifications/kstatusnotifieritemdbus_p.h

it is in the interface file:
kdeui/notifications/org.kde.StatusNotifierItem.xml

but not implemented in the D-Bus interface

Signed-off-by: Ivailo Monev <xakepa10@gmail.com>
2022-09-28 16:59:19 +03:00

394 lines
12 KiB
C++

/***************************************************************************
* *
* Copyright (C) 2009 Marco Martin <notmart@gmail.com> *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . *
***************************************************************************/
#include "dbussystemtraytask.h"
#include "dbussystemtrayprotocol.h"
#include <QtCore/qmetaobject.h>
#include <QtCore/QDir>
#include <QtCore/QCoreApplication>
#include <QtGui/QMenu>
#include <QtGui/QIcon>
#include <KJob>
#include <KIcon>
#include <KIconLoader>
#include <KStandardDirs>
#include <Plasma/ServiceJob>
#include <Plasma/ToolTipManager>
#include <Plasma/Applet>
#include <KDebug>
namespace SystemTray
{
DBusSystemTrayTask::DBusSystemTrayTask(const QString &serviceName, Plasma::DataEngine *dataEngine, QObject *parent)
: Task(parent),
m_serviceName(serviceName),
m_taskId(serviceName),
m_customIconLoader(0),
m_dataEngine(dataEngine),
m_service(dataEngine->serviceForSource(serviceName)),
m_isMenu(false),
m_valid(false)
{
kDebug();
m_service->setParent(this);
m_dataEngine->connectSource(serviceName, this);
}
DBusSystemTrayTask::~DBusSystemTrayTask()
{
}
QGraphicsWidget* DBusSystemTrayTask::createWidget(Plasma::Applet */*host*/)
{
return 0; // d-bus tasks don't have widgets but provide info for GUI;
}
bool DBusSystemTrayTask::isValid() const
{
return m_valid;
}
bool DBusSystemTrayTask::isEmbeddable() const
{
return false; // this task cannot be embed because it only provides information to GUI part
}
bool DBusSystemTrayTask::isWidget() const
{
return false; // isn't a widget
}
void DBusSystemTrayTask::setShortcut(QString text) {
if (m_shortcut != text) {
m_shortcut = text;
emit changedShortcut();
}
}
QString DBusSystemTrayTask::taskId() const
{
return m_taskId;
}
QIcon DBusSystemTrayTask::icon() const
{
return m_icon;
}
void DBusSystemTrayTask::activate1(int x, int y) const
{
KConfigGroup params;
if (m_isMenu) {
params = m_service->operationDescription("ContextMenu");
} else {
params = m_service->operationDescription("Activate");
}
params.writeEntry("x", x);
params.writeEntry("y", y);
KJob *job = m_service->startOperationCall(params);
connect(job, SIGNAL(result(KJob*)), this, SLOT(_onContextMenu(KJob*)));
}
void DBusSystemTrayTask::activate2(int x, int y) const
{
KConfigGroup params = m_service->operationDescription("SecondaryActivate");
params.writeEntry("x", x);
params.writeEntry("y", y);
m_service->startOperationCall(params);
}
void DBusSystemTrayTask::activateHorzScroll(int delta) const
{
_activateScroll(delta, "Horizontal");
}
// Copied from kde-runtime/plasma/declarativeimports/core/iconitem.cpp
bool static hasm_svgIcon(QVariant source)
{
// Set up compat envrionment, afterwards it is 100% copy'n'pastable.
const QString element = source.toString();
const QString filename = element.split("-").first();
Plasma::Svg svgIcon;
Plasma::Svg *m_svgIcon = &svgIcon;
//try as a svg toolbar icon
m_svgIcon->setImagePath("toolbar-icons/" + filename);
//try as a svg normal icon (like systray)
if (!m_svgIcon->isValid() || !m_svgIcon->hasElement(element)) {
m_svgIcon->setImagePath("icons/" + filename);
}
m_svgIcon->setContainsMultipleImages(true);
//success?
if (m_svgIcon->isValid() && m_svgIcon->hasElement(element)) {
return true;
}
return false;
}
QVariant DBusSystemTrayTask::customIcon(QVariant variant) const
{
if (variant.canConvert<QString>()) {
// If we have no icon loader there is nothing to be done with strings.
if (!m_customIconLoader)
return variant;
// If an SVG icon can be found (via Plasma theme) the name needs to be
// passed along for IconItem to be able to resolve to the theme name as
// well.
if (hasm_svgIcon(variant))
return variant;
// Otherwise return a QIcon from our custom icon loader.
return QVariant(KIcon(variant.toString(), m_customIconLoader));
} else {
// Most importantly QIcons. Nothing to do for those.
return variant;
}
}
void DBusSystemTrayTask::activateVertScroll(int delta) const
{
_activateScroll(delta, "Vertical");
}
void DBusSystemTrayTask::_activateScroll(int delta, QString direction) const
{
KConfigGroup params = m_service->operationDescription("Scroll");
params.writeEntry("delta", delta);
params.writeEntry("direction", direction);
m_service->startOperationCall(params);
}
void DBusSystemTrayTask::activateContextMenu(int x, int y) const
{
KConfigGroup params = m_service->operationDescription("ContextMenu");
params.writeEntry("x", x);
params.writeEntry("y", y);
KJob *job = m_service->startOperationCall(params);
connect(job, SIGNAL(result(KJob*)), this, SLOT(_onContextMenu(KJob*)));
}
void DBusSystemTrayTask::_onContextMenu(KJob *job)
{
if (QCoreApplication::closingDown()) {
// apparently an edge case can be triggered due to the async nature of all this
// see: https://bugs.kde.org/show_bug.cgi?id=251977
return;
}
Plasma::ServiceJob *sjob = qobject_cast<Plasma::ServiceJob *>(job);
if (!sjob) {
return;
}
QMenu *menu = qobject_cast<QMenu *>(sjob->result().value<QObject *>());
if (menu) {
int x = sjob->parameters()["x"].toInt();
int y = sjob->parameters()["y"].toInt();
emit showContextMenu(x, y, QVariant::fromValue<QObject*>(menu));
}
}
void DBusSystemTrayTask::dataUpdated(const QString &taskName, const Plasma::DataEngine::Data &properties)
{
Q_UNUSED(taskName);
const QString id = properties["Id"].toString();
bool becomeValid = false;
if (!id.isEmpty() && id != m_taskId) {
m_taskId = id;
m_valid = true;
becomeValid = true;
setObjectName(QString("SystemTray-%1").arg(m_taskId));
}
QString cat = properties["Category"].toString();
if (!cat.isEmpty()) {
int index = metaObject()->indexOfEnumerator("Category");
int key = metaObject()->enumerator(index).keyToValue(cat.toLatin1());
if (key != -1) {
setCategory((Task::Category)key);
}
}
if (properties["TitleChanged"].toBool() || becomeValid) {
QString title = properties["Title"].toString();
if (!title.isEmpty()) {
bool is_title_changed = (name() != title);
setName(title);
if (is_title_changed) {
emit changedTitle();
emit changed(this);
}
}
}
if (properties["IconsChanged"].toBool() || becomeValid) {
syncIcons(properties);
emit changedIcons();
}
if (properties["StatusChanged"].toBool() || becomeValid) {
syncStatus(properties["Status"].toString());
}
if (properties["ToolTipChanged"].toBool() || becomeValid) {
syncToolTip(properties["ToolTipTitle"].toString(),
properties["ToolTipSubTitle"].toString(),
properties["ToolTipIcon"].value<QIcon>());
}
bool is_menu = properties["ItemIsMenu"].toBool();
if (is_menu != m_isMenu) {
m_isMenu = is_menu;
emit changedIsMenu();
}
if (becomeValid) {
DBusSystemTrayProtocol *protocol = qobject_cast<DBusSystemTrayProtocol*>(parent());
if (protocol) {
protocol->initedTask(this);
}
}
}
void DBusSystemTrayTask::syncIcons(const Plasma::DataEngine::Data &properties)
{
m_icon = properties["Icon"].value<QIcon>();
m_attentionIcon = properties["AttentionIcon"].value<QIcon>();
QString icon_name = properties["IconName"].toString();
QString att_icon_name = properties["AttentionIconName"].toString();
QString overlay_icon_name = properties["OverlayIconName"].value<QString>();
QString icon_theme_path = properties["IconThemePath"].value<QString>();
bool is_icon_name_changed = false;
bool is_att_icon_name_changed = false;
bool is_overlay_icon_name_changed = false;
if (icon_name != m_iconName) {
m_iconName = icon_name;
is_icon_name_changed = true;
}
if (att_icon_name != m_attentionIconName) {
m_attentionIconName = att_icon_name;
is_att_icon_name_changed = true;
}
if (overlay_icon_name != m_overlayIconName) {
m_overlayIconName = overlay_icon_name;
is_overlay_icon_name_changed = true;
}
if (icon_theme_path != m_iconThemePath) {
m_iconThemePath = icon_theme_path;
if (m_customIconLoader) {
delete m_customIconLoader;
m_customIconLoader = 0;
}
const QString path = m_iconThemePath;
if (!path.isEmpty()) {
QStringList tokens = path.split('/', QString::SkipEmptyParts);
if (tokens.length() >= 3) {
QString appName = tokens.takeLast();
QString prefix = QChar('/') + tokens.join("/");
// FIXME: Fix KIconLoader and KIconTheme so that we can use
// our own instance of KStandardDirs
KGlobal::dirs()->addResourceDir("data", prefix);
// We use a separate instance of KIconLoader to avoid
// adding all application dirs to KIconLoader::global(), to
// avoid potential icon name clashes between application
// icons
m_customIconLoader = new KIconLoader(appName, 0 /* dirs */, this);
} else {
kWarning() << "Wrong IconThemePath" << path << ": too short or does not end with 'icons'";
}
}
// Trigger updates
is_icon_name_changed = true;
is_att_icon_name_changed = true;
is_overlay_icon_name_changed = true;
emit changedIcons();
}
// emit signals
if (is_icon_name_changed) {
emit changedIconName();
}
if (is_att_icon_name_changed) {
emit changedAttIconName();
}
if (is_overlay_icon_name_changed) {
emit changedOverlayIconName();
}
}
//toolTip
void DBusSystemTrayTask::syncToolTip(const QString &title, const QString &subTitle, const QIcon &toolTipIcon)
{
if (title != m_tooltipTitle) {
m_tooltipTitle = title;
emit changedTooltipTitle();
}
if (subTitle != m_tooltipText) {
m_tooltipText = subTitle;
emit changedTooltipText();
}
bool is_icon_name_changed = (m_tooltipIcon.name() != toolTipIcon.name());
m_tooltipIcon = toolTipIcon;
emit changedTooltip();
if (is_icon_name_changed) {
emit changedTooltipIconName();
}
}
//Status
void DBusSystemTrayTask::syncStatus(QString newStatus)
{
Task::Status status = (Task::Status)metaObject()->enumerator(metaObject()->indexOfEnumerator("Status")).keyToValue(newStatus.toLatin1());
if (this->status() == status) {
return;
}
setStatus(status);
}
}
#include "moc_dbussystemtraytask.cpp"