2 * Copyright 2014 Canonical Ltd.
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published by
6 * the Free Software Foundation; version 3.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 * Michael Zanetti <michael.zanetti@canonical.com>
20#include "dbusinterface.h"
21#include "launchermodel.h"
22#include "launcheritem.h"
24#include <QDBusArgument>
25#include <QDBusConnection>
26#include <QDBusMessage>
29DBusInterface::DBusInterface(LauncherModel *parent):
30 QDBusVirtualObject(parent),
31 m_launcherModel(parent)
33 /* Set up ourselves on DBus */
34 QDBusConnection con = QDBusConnection::sessionBus();
35 if (!con.registerService("com.canonical.Unity.Launcher")) {
36 qWarning() << "Unable to register launcher name";
38 if (!con.registerVirtualObject("/com/canonical/Unity/Launcher", this, QDBusConnection::VirtualObjectRegisterOption::SubPath)) {
39 qWarning() << "Unable to register launcher object";
43DBusInterface::~DBusInterface()
45 /* Remove oursevles from DBus */
46 QDBusConnection con = QDBusConnection::sessionBus();
47 con.unregisterService("com.canonical.Unity.Launcher");
48 con.unregisterObject("/com/canonical/Unity/Launcher");
51QString DBusInterface::introspect(const QString &path) const
53 /* This case we should just list the nodes */
54 if (path == "/com/canonical/Unity/Launcher/" || path == "/com/canonical/Unity/Launcher") {
57 // Add Refresh to introspect
58 nodes = "<interface name=\"com.canonical.Unity.Launcher\">"
59 "<method name=\"Refresh\"/>"
62 // Add dynamic properties for launcher emblems
63 for (int i = 0; i < m_launcherModel->rowCount(); i++) {
64 nodes.append("<node name=\"");
65 nodes.append(encodeAppId(m_launcherModel->get(i)->appId()));
66 nodes.append("\"/>\n");
71 /* Should not happen, but let's handle it */
72 if (!path.startsWith("/com/canonical/Unity/Launcher")) {
76 /* Now we should be looking at a node */
78 "<interface name=\"com.canonical.Unity.Launcher.Item\">"
79 "<property name=\"count\" type=\"i\" access=\"readwrite\" />"
80 "<property name=\"countVisible\" type=\"b\" access=\"readwrite\" />"
86QString DBusInterface::decodeAppId(const QString& path)
88 QByteArray bytes = path.toUtf8();
91 for (int i = 0; i < bytes.size(); ++i) {
92 char chr = bytes.at(i);
96 number.append(bytes.at(i+1));
97 number.append(bytes.at(i+2));
100 char newchar = number.toUInt(&okay, 16);
102 decoded.append(newchar);
110 return QString::fromUtf8(decoded);
113QString DBusInterface::encodeAppId(const QString& appId)
115 QByteArray bytes = appId.toUtf8();
118 for (int i = 0; i < bytes.size(); ++i) {
119 uchar chr = bytes.at(i);
121 if ((chr >= 'a' && chr <= 'z') ||
122 (chr >= 'A' && chr <= 'Z') ||
123 (chr >= '0' && chr <= '9'&& i != 0)) {
126 QString hexval = QString("_%1").arg(chr, 2, 16, QChar('0'));
127 encoded.append(hexval.toUpper());
134bool DBusInterface::handleMessage(const QDBusMessage& message, const QDBusConnection& connection)
136 /* Check to make sure we're getting properties on our interface */
137 if (message.type() != QDBusMessage::MessageType::MethodCallMessage) {
141 // First handle methods of the Launcher interface
142 if (message.interface() == "com.canonical.Unity.Launcher") {
143 if (message.member() == "Refresh") {
144 QDBusMessage reply = message.createReply();
145 Q_EMIT refreshCalled();
146 return connection.send(reply);
150 // Now handle dynamic properties (for launcher emblems)
151 if (message.interface() != "org.freedesktop.DBus.Properties") {
155 if (message.member() != "GetAll" && message.arguments()[0].toString() != "com.canonical.Unity.Launcher.Item") {
159 /* Break down the path to just the app id */
160 QString pathtemp = message.path();
161 if (!pathtemp.startsWith("/com/canonical/Unity/Launcher/")) {
164 pathtemp.remove("/com/canonical/Unity/Launcher/");
165 if (pathtemp.indexOf('/') >= 0) {
169 /* Find ourselves an appid */
170 QString appid = decodeAppId(pathtemp);
171 int index = m_launcherModel->findApplication(appid);
172 LauncherItem *item = static_cast<LauncherItem*>(m_launcherModel->get(index));
175 if (message.member() == "Get") {
179 if (message.arguments()[1].toString() == "count") {
180 retval.append(QVariant::fromValue(QDBusVariant(item->count())));
181 } else if (message.arguments()[1].toString() == "countVisible") {
182 retval.append(QVariant::fromValue(QDBusVariant(item->countVisible())));
184 } else if (message.member() == "Set") {
185 if (message.arguments()[1].toString() == "count") {
186 int newCount = message.arguments()[2].toInt();
187 if (!item || newCount != item->count()) {
188 Q_EMIT countChanged(appid, newCount);
189 emitPropChangedDbus(appid, "count", QVariant(newCount));
191 } else if (message.arguments()[1].toString() == "countVisible") {
192 bool newVisible = message.arguments()[2].toBool();
193 if (!item || newVisible != item->countVisible()) {
194 Q_EMIT countVisibleChanged(appid, newVisible);
195 emitPropChangedDbus(appid, "countVisible", newVisible);
198 } else if (message.member() == "GetAll") {
201 all.insert("count", item->count());
202 all.insert("countVisible", item->countVisible());
209 QDBusMessage reply = message.createReply(retval);
210 return connection.send(reply);
213void DBusInterface::emitPropChangedDbus(const QString& appId, const QString& property, const QVariant &value)
215 QString path("/com/canonical/Unity/Launcher/");
216 path.append(encodeAppId(appId));
218 QDBusMessage message = QDBusMessage::createSignal(path, "org.freedesktop.DBus.Properties", "PropertiesChanged");
220 QList<QVariant> arguments;
221 QVariantHash changedprops;
222 changedprops[property] = QVariant::fromValue(QDBusVariant(value));
223 QVariantList deletedprops;
225 arguments.append(changedprops);
226 arguments.append(deletedprops);
228 message.setArguments(arguments);
230 QDBusConnection con = QDBusConnection::sessionBus();
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list