You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

329 lines
9.7 KiB

/***************************************************************************
* Copyright 2013 Sebastian Kügler <sebas@kde.org> *
* *
* 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 "plasmoidtask.h"
#include "plasmoidprotocol.h"
#include "../../host.h"
#include "debug.h"
#include <QtCore/QMetaEnum>
#include <QAction>
#include <QQuickWindow>
#include <kdeclarative/qmlobject.h>
#include <KActionCollection>
#include <KPluginInfo>
#include <KLocalizedString>
#include <QLoggingCategory>
#include <QMenu>
#include <Plasma/Applet>
#include <Plasma/PluginLoader>
#include "appletquickitem.h"
#include "config-workspace.h"
namespace SystemTray
{
PlasmoidTask::PlasmoidTask(const QString &packageName, int appletId, Plasma::Containment *cont, QObject *parent)
: Task(parent),
m_taskId(packageName),
m_applet(0),
m_valid(false)
{
qCDebug(SYSTEMTRAY) << "Loading applet: " << packageName << appletId;
m_applet = Plasma::PluginLoader::self()->loadApplet(packageName, appletId);
if (!m_applet) {
qWarning() << "could not load plasma applet " << packageName << appletId;
return;
}
m_valid = true;
cont->setImmutability(Plasma::Types::Mutable);
cont->addApplet(m_applet);
m_applet->setParent(cont);
//FIXME? This is *maybe* not necessary
m_applet->init();
m_taskGraphicsObject = m_applet->property("_plasma_graphicObject").value<PlasmaQuick::AppletQuickItem *>();
if (m_taskGraphicsObject) {
/*override any default size for applets, in the systray the size is NEVER
* controlled by applet itself. This caused some plasmoids like
* klipper getting expanded for an instant before collapsing again
*/
m_taskGraphicsObject->setWidth(0);
m_taskGraphicsObject->setHeight(0);
Plasma::Package package = Plasma::PluginLoader::self()->loadPackage("Plasma/Shell");
package.setDefaultPackageRoot(PLASMA_RELATIVE_DATA_INSTALL_DIR "/plasmoids/");
package.setPath("org.kde.plasma.systemtray");
m_taskGraphicsObject->setCoronaPackage(package);
QMetaObject::invokeMethod(m_taskGraphicsObject, "init", Qt::QueuedConnection);
//old syntax, because we are connecting blindly
connect(m_taskGraphicsObject, SIGNAL(expandedChanged(bool)),
this, SIGNAL(expandedChanged(bool)));
}
if (!m_applet) {
qCDebug(SYSTEMTRAY) << "Invalid applet taskitem";
m_valid = false;
return;
}
connect(m_applet, &Plasma::Applet::statusChanged, this, &PlasmoidTask::updateStatus);
if (pluginInfo().isValid()) {
setName(pluginInfo().name());
m_iconName = pluginInfo().icon();
const QString category = pluginInfo().property("X-Plasma-NotificationAreaCategory").toString();
if (!category.isEmpty()) {
int index = metaObject()->indexOfEnumerator("Category");
int key = metaObject()->enumerator(index).keyToValue(category.toLatin1());
if (key != -1) {
setCategory(static_cast<Task::Category>(key));
}
}
} else {
qWarning() << "Invalid Plasmoid: " << packageName;
}
updateStatus();
}
PlasmoidTask::~PlasmoidTask()
{
}
KPluginInfo PlasmoidTask::pluginInfo() const
{
if (!m_applet) {
return KPluginInfo();
}
return m_applet->pluginInfo();
}
void PlasmoidTask::updateStatus()
{
if (!m_applet || !pluginInfo().isValid()) {
return;
}
const Plasma::Types::ItemStatus ps = m_applet->status();
if (ps == Plasma::Types::UnknownStatus) {
setStatus(Task::UnknownStatus);
} else if (ps == Plasma::Types::PassiveStatus) {
setStatus(Task::Passive);
} else if (ps == Plasma::Types::NeedsAttentionStatus) {
setStatus(Task::NeedsAttention);
} else {
setStatus(Task::Active);
}
}
bool PlasmoidTask::isValid() const
{
return m_valid && pluginInfo().isValid();
}
bool PlasmoidTask::isEmbeddable() const
{
return false; // this task cannot be embed because it only provides information to GUI part
}
bool PlasmoidTask::isWidget() const
{
return false; // isn't a widget
}
QKeySequence PlasmoidTask::shortcut() const
{
return m_applet->globalShortcut();
}
void PlasmoidTask::setShortcut(const QKeySequence &sequence)
{
if (m_applet->globalShortcut() != sequence) {
m_applet->setGlobalShortcut(sequence);
emit changedShortcut();
}
}
void PlasmoidTask::configure()
{
if (!m_applet) {
return;
}
m_applet->actions()->action("configure")->trigger();
}
void PlasmoidTask::setLocation(Plasma::Types::Location loc)
{
if (m_applet) {
// m_applet->setLocation(loc);
}
}
QString PlasmoidTask::taskId() const
{
return m_taskId;
}
QQuickItem* PlasmoidTask::taskItem()
{
if (m_taskGraphicsObject) {
return m_taskGraphicsObject;
}
//FIXME
return new QQuickItem();//m_applet;
}
QQuickItem* PlasmoidTask::taskItemExpanded()
{
if (!m_applet) {
return 0;
}
if (m_taskGraphicsObject && m_taskGraphicsObject->property("fullRepresentationItem").value<QQuickItem *>()) {
return m_taskGraphicsObject->property("fullRepresentationItem").value<QQuickItem *>();
}
//FIXME
return new QQuickItem();//m_applet->defaultRepresentation();
}
QIcon PlasmoidTask::icon() const
{
return m_icon;
}
//Status
void PlasmoidTask::syncStatus(QString newStatus)
{
Task::Status status = (Task::Status)metaObject()->enumerator(metaObject()->indexOfEnumerator("Status")).keyToValue(newStatus.toLatin1());
if (this->status() == status) {
return;
}
setStatus(status);
}
bool PlasmoidTask::expanded() const
{
if (m_taskGraphicsObject) {
return m_taskGraphicsObject->property("expanded").toBool();
} else {
return false;
}
}
void PlasmoidTask::setExpanded(bool expanded)
{
if (m_taskGraphicsObject) {
m_taskGraphicsObject->setProperty("expanded", expanded);
}
}
void PlasmoidTask::showMenu(int x, int y)
{
QPoint pos(x, y);
QQuickWindow *w = 0;
if (taskItem()) {
w = taskItem()->window();
}
if (w) {
pos = taskItem()->mapToScene(pos).toPoint() + w->position();
}
QMenu desktopMenu;
foreach (QAction *action, m_applet->contextualActions()) {
if (action) {
desktopMenu.addAction(action);
}
}
if (m_applet->actions()->action("configure")) {
desktopMenu.addAction(m_applet->actions()->action("configure"));
}
if (parent() && parent()->parent()) {
Host* h = qobject_cast<Host*>(parent()->parent());
if (h) {
QQuickItem* rootItem = h->rootItem();
if (rootItem) {
Plasma::Applet *systrayApplet = rootItem->property("_plasma_applet").value<Plasma::Applet*>();
if (systrayApplet) {
QMenu *systrayMenu = new QMenu(i18n("System Tray Options"), &desktopMenu);
foreach (QAction *action, systrayApplet->contextualActions()) {
if (action) {
systrayMenu->addAction(action);
}
}
if (systrayApplet->actions()->action("configure")) {
systrayMenu->addAction(systrayApplet->actions()->action("configure"));
}
if (systrayApplet->actions()->action("remove")) {
systrayMenu->addAction(systrayApplet->actions()->action("remove"));
}
desktopMenu.addMenu(systrayMenu);
if (systrayApplet->containment() && status() >= Active) {
QMenu *containmentMenu = new QMenu(i18nc("%1 is the name of the containment", "%1 Options", systrayApplet->containment()->title()), &desktopMenu);
foreach (QAction *action, systrayApplet->containment()->contextualActions()) {
if (action) {
containmentMenu->addAction(action);
}
}
foreach (QAction *action, systrayApplet->containment()->actions()->actions()) {
if (action) {
containmentMenu->addAction(action);
}
}
desktopMenu.addMenu(containmentMenu);
}
}
}
}
}
desktopMenu.exec(pos);
}
Plasma::Applet *PlasmoidTask::applet()
{
return m_applet;
}
}