~ubuntu-branches/ubuntu/trusty/hud/trusty-updates

« back to all changes in this revision

Viewing changes to service/DBusMenuCollector.cpp

  • Committer: Package Import Robot
  • Author(s): Ubuntu daily release
  • Date: 2014-01-20 19:43:59 UTC
  • mfrom: (1.1.26)
  • Revision ID: package-import@ubuntu.com-20140120194359-jxxxqtd4ql9elvpf
Tags: 13.10.1+14.04.20140120-0ubuntu1
* New rebuild forced
* Automatic snapshot from revision 362

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (C) 2013 Canonical, Ltd.
 
3
 *
 
4
 * This program is free software: you can redistribute it and/or modify it
 
5
 * under the terms of the GNU General Public License version 3, as published
 
6
 * by the Free Software Foundation.
 
7
 *
 
8
 * This program is distributed in the hope that it will be useful, but
 
9
 * WITHOUT ANY WARRANTY; without even the implied warranties of
 
10
 * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
 
11
 * PURPOSE.  See the GNU General Public License for more details.
 
12
 *
 
13
 * You should have received a copy of the GNU General Public License along
 
14
 * with this program.  If not, see <http://www.gnu.org/licenses/>.
 
15
 *
 
16
 * Author: Pete Woods <pete.woods@canonical.com>
 
17
 */
 
18
 
 
19
#include <common/DBusTypes.h>
 
20
#include <common/Localisation.h>
 
21
#include <service/DBusMenuCollector.h>
 
22
#include <service/AppmenuRegistrarInterface.h>
 
23
 
 
24
#include <dbusmenuimporter.h>
 
25
#include <QMenu>
 
26
#include <columbus.hh>
 
27
 
 
28
using namespace hud::common;
 
29
using namespace hud::service;
 
30
 
 
31
DBusMenuCollector::DBusMenuCollector(unsigned int windowId,
 
32
                QSharedPointer<ComCanonicalAppMenuRegistrarInterface> registrar) :
 
33
                m_windowId(windowId), m_registrar(registrar) {
 
34
 
 
35
        connect(registrar.data(),
 
36
        SIGNAL(WindowRegistered(uint, const QString &, const QDBusObjectPath &)),
 
37
                        this,
 
38
                        SLOT( WindowRegistered(uint, const QString &, const QDBusObjectPath &)));
 
39
 
 
40
        connect(registrar.data(), SIGNAL(
 
41
                        WindowUnregistered(uint)), this, SLOT(WindowUnregistered(uint)));
 
42
 
 
43
        QDBusPendingReply<QString, QDBusObjectPath> windowReply =
 
44
                        registrar->GetMenuForWindow(m_windowId);
 
45
 
 
46
        windowReply.waitForFinished();
 
47
        if (windowReply.isError()) {
 
48
                return;
 
49
        }
 
50
 
 
51
        windowRegistered(windowReply.argumentAt<0>(), windowReply.argumentAt<1>());
 
52
}
 
53
 
 
54
DBusMenuCollector::~DBusMenuCollector() {
 
55
}
 
56
 
 
57
void DBusMenuCollector::windowRegistered(const QString &service,
 
58
                const QDBusObjectPath &menuObjectPath) {
 
59
        m_service = service;
 
60
        m_path = menuObjectPath;
 
61
 
 
62
        if (m_service.isEmpty()) {
 
63
                m_menuImporter.reset();
 
64
                return;
 
65
        }
 
66
 
 
67
        m_menuImporter.reset(new DBusMenuImporter(m_service, m_path.path()));
 
68
 
 
69
        CollectorToken::Ptr collectorToken(m_collectorToken);
 
70
        if(collectorToken) {
 
71
                collectorToken->changed();
 
72
        }
 
73
}
 
74
 
 
75
bool DBusMenuCollector::isValid() const {
 
76
        return !m_menuImporter.isNull();
 
77
}
 
78
 
 
79
inline uint qHash(const QStringList &key, uint seed) {
 
80
        uint hash(0);
 
81
        for (const QString &s : key) {
 
82
                hash ^= qHash(s, seed);
 
83
        }
 
84
        return hash;
 
85
}
 
86
 
 
87
static void openMenu(QMenu *menu) {
 
88
        if (!menu) {
 
89
                return;
 
90
        }
 
91
 
 
92
        menu->aboutToShow();
 
93
 
 
94
        for (int i(0); i < menu->actions().size(); ++i) {
 
95
                QAction *action = menu->actions().at(i);
 
96
                if (!action->isEnabled()) {
 
97
                        continue;
 
98
                }
 
99
                if (action->isSeparator()) {
 
100
                        continue;
 
101
                }
 
102
 
 
103
                QMenu *child(action->menu());
 
104
                if (child) {
 
105
                        openMenu(child);
 
106
                }
 
107
        }
 
108
}
 
109
 
 
110
static void hideMenu(QMenu *menu) {
 
111
        for (int i(0); i < menu->actions().size(); ++i) {
 
112
                QAction *action = menu->actions().at(i);
 
113
                QMenu *child(action->menu());
 
114
                if (child) {
 
115
                        hideMenu(child);
 
116
                }
 
117
        }
 
118
 
 
119
        menu->aboutToHide();
 
120
}
 
121
 
 
122
CollectorToken::Ptr DBusMenuCollector::activate() {
 
123
        CollectorToken::Ptr collectorToken(m_collectorToken);
 
124
 
 
125
        if (collectorToken.isNull()) {
 
126
                openMenu(m_menuImporter->menu());
 
127
                collectorToken.reset(
 
128
                                new CollectorToken(shared_from_this(), m_menuImporter->menu()));
 
129
                m_collectorToken = collectorToken;
 
130
        }
 
131
 
 
132
        return collectorToken;
 
133
}
 
134
 
 
135
void DBusMenuCollector::deactivate() {
 
136
        hideMenu(m_menuImporter->menu());
 
137
}
 
138
 
 
139
void DBusMenuCollector::WindowRegistered(uint windowId, const QString &service,
 
140
                const QDBusObjectPath &menuObjectPath) {
 
141
        // Simply ignore updates for other windows
 
142
        if (windowId != m_windowId) {
 
143
                return;
 
144
        }
 
145
 
 
146
        windowRegistered(service, menuObjectPath);
 
147
}
 
148
 
 
149
void DBusMenuCollector::WindowUnregistered(uint windowId) {
 
150
        // Simply ignore updates for other windows
 
151
        if (windowId != m_windowId) {
 
152
                return;
 
153
        }
 
154
 
 
155
        m_menuImporter.reset();
 
156
}