~agateau/unity-2d/edge-reveal

« back to all changes in this revision

Viewing changes to panel/applets/appmenu/appmenuapplet.cpp

  • Committer: Aurelien Gateau
  • Date: 2010-10-06 13:52:55 UTC
  • Revision ID: aurelien.gateau@canonical.com-20101006135255-j4gsdm7k3grh0ydh
Merged in panel

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * This file is part of unity-qt
 
3
 *
 
4
 * Copyright 2010 Canonical Ltd.
 
5
 *
 
6
 * Authors:
 
7
 * - Aurélien Gâteau <aurelien.gateau@canonical.com>
 
8
 *
 
9
 * License: GPL v3
 
10
 */
 
11
// Self
 
12
#include "appmenuapplet.h"
 
13
 
 
14
// Local
 
15
#include "debug_p.h"
 
16
#include "registrar.h"
 
17
 
 
18
// dbusmenu-qt
 
19
#include <dbusmenuimporter.h>
 
20
 
 
21
// bamf
 
22
#include <bamf-matcher.h>
 
23
#include <bamf-window.h>
 
24
 
 
25
// Qt
 
26
#include <QHBoxLayout>
 
27
#include <QMenuBar>
 
28
 
 
29
class MyDBusMenuImporter : public DBusMenuImporter
 
30
{
 
31
public:
 
32
    MyDBusMenuImporter(const QString &service, const QString &path, QObject *parent)
 
33
    : DBusMenuImporter(service, path, parent)
 
34
    , m_service(service)
 
35
    , m_path(path)
 
36
    {}
 
37
 
 
38
    QString service() const { return m_service; }
 
39
    QString path() const { return m_path; }
 
40
 
 
41
private:
 
42
    QString m_service;
 
43
    QString m_path;
 
44
};
 
45
 
 
46
AppMenuApplet::AppMenuApplet()
 
47
{
 
48
    m_activeWinId = 0;
 
49
    setupRegistrar();
 
50
    setupMenuBar();
 
51
 
 
52
    connect(&BamfMatcher::get_default(), SIGNAL(ActiveWindowChanged(BamfWindow*, BamfWindow*)),
 
53
        SLOT(slotActiveWindowChanged(BamfWindow*, BamfWindow*)));
 
54
    updateActiveWinId(BamfMatcher::get_default().active_window());
 
55
}
 
56
 
 
57
void AppMenuApplet::setupRegistrar()
 
58
{
 
59
    m_registrar = new Registrar(this);
 
60
    if (!m_registrar->connectToBus()) {
 
61
        UQ_WARNING << "could not connect registrar to DBus";
 
62
    }
 
63
 
 
64
    connect(m_registrar, SIGNAL(WindowRegistered(WId, const QString&, const QDBusObjectPath&)),
 
65
        SLOT(slotWindowRegistered(WId, const QString&, const QDBusObjectPath&)));
 
66
}
 
67
 
 
68
void AppMenuApplet::setupMenuBar()
 
69
{
 
70
    QHBoxLayout* layout = new QHBoxLayout(this);
 
71
    layout->setMargin(0);
 
72
    m_menuBar = new QMenuBar;
 
73
    layout->addWidget(m_menuBar);
 
74
    m_menuBar->setNativeMenuBar(false);
 
75
    m_menuBar->addMenu("File");
 
76
}
 
77
 
 
78
void AppMenuApplet::slotActiveWindowChanged(BamfWindow* /*former*/, BamfWindow* current)
 
79
{
 
80
    if (current) {
 
81
        updateActiveWinId(current);
 
82
    }
 
83
}
 
84
 
 
85
void AppMenuApplet::slotWindowRegistered(WId wid, const QString& service, const QDBusObjectPath& menuObjectPath)
 
86
{
 
87
    MyDBusMenuImporter* importer = new MyDBusMenuImporter(service, menuObjectPath.path(), this);
 
88
    delete m_importers.take(wid);
 
89
    m_importers.insert(wid, importer);
 
90
    connect(importer, SIGNAL(menuUpdated()), SLOT(slotMenuUpdated()));
 
91
    connect(importer, SIGNAL(actionActivationRequested(QAction*)), SLOT(slotActionActivationRequested(QAction*)));
 
92
    QMetaObject::invokeMethod(importer, "updateMenu", Qt::QueuedConnection);
 
93
}
 
94
 
 
95
void AppMenuApplet::slotMenuUpdated()
 
96
{
 
97
    DBusMenuImporter* importer = static_cast<DBusMenuImporter*>(sender());
 
98
 
 
99
    if (m_importers.value(m_activeWinId) == importer) {
 
100
        updateMenuBar();
 
101
    }
 
102
}
 
103
 
 
104
void AppMenuApplet::slotActionActivationRequested(QAction* action)
 
105
{
 
106
    DBusMenuImporter* importer = static_cast<DBusMenuImporter*>(sender());
 
107
 
 
108
    if (m_importers.value(m_activeWinId) == importer) {
 
109
        m_menuBar->setActiveAction(action);
 
110
    }
 
111
}
 
112
 
 
113
QMenu* AppMenuApplet::menuForWinId(WId wid) const
 
114
{
 
115
    MyDBusMenuImporter* importer = m_importers.value(wid);
 
116
    return importer ? importer->menu() : 0;
 
117
}
 
118
 
 
119
void AppMenuApplet::updateActiveWinId(BamfWindow* window)
 
120
{
 
121
    WId id = window ? window->xid() : 0;
 
122
    if (id == m_activeWinId) {
 
123
        return;
 
124
    }
 
125
    UQ_VAR(id);
 
126
    UQ_VAR(this->window()->winId());
 
127
    if (id == this->window()->winId()) {
 
128
        // Do not update id if the active window is the one hosting this applet
 
129
        UQ_DEBUG << "No update";
 
130
        return;
 
131
    }
 
132
    m_activeWinId = id;
 
133
    updateMenuBar();
 
134
}
 
135
 
 
136
void AppMenuApplet::updateMenuBar()
 
137
{
 
138
    UQ_DEBUG;
 
139
    WId winId = m_activeWinId;
 
140
    QMenu* menu = menuForWinId(winId);
 
141
 
 
142
    if (!menu) {
 
143
        if (winId) {
 
144
            // We have an active window
 
145
            // FIXME: transient check
 
146
            /*
 
147
            WId mainWinId = KWindowSystem::transientFor(winId);
 
148
            if (mainWinId) {
 
149
                // We have a parent window, use a disabled version of its
 
150
                // menubar if it has one.
 
151
                QMenu* mainMenu = menuForWinId(mainWinId);
 
152
                if (mainMenu) {
 
153
                    mMenuCloner->setOriginalMenu(mainMenu);
 
154
                    menu = mMenuCloner->clonedMenu();
 
155
                }
 
156
            }*/
 
157
            // FIXME: WindowMenuManager
 
158
            /*
 
159
            if (!menu) {
 
160
                // No suitable menubar but we have a window, use the
 
161
                // generic window menu
 
162
                mWindowMenuManager->setWinId(winId);
 
163
                menu = mWindowMenu;
 
164
            }
 
165
            */
 
166
        } else {
 
167
            // No active window, show a desktop menubar
 
168
            // FIXME: Empty menu
 
169
            /*
 
170
            menu = mEmptyMenu;
 
171
            */
 
172
        }
 
173
    }
 
174
    UQ_VAR(menu);
 
175
    fillMenuBar(menu);
 
176
}
 
177
 
 
178
void AppMenuApplet::fillMenuBar(QMenu* menu)
 
179
{
 
180
    m_menuBar->clear();
 
181
    // FIXME: Empty menu
 
182
    if (!menu) {
 
183
        return;
 
184
    }
 
185
    Q_FOREACH(QAction* action, menu->actions()) {
 
186
        if (action->isSeparator()) {
 
187
            continue;
 
188
        }
 
189
        m_menuBar->addAction(action);
 
190
    }
 
191
}
 
192
 
 
193
#include "appmenuapplet.moc"