~sil2100/unity-2d/precise-security

« back to all changes in this revision

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

  • Committer: Aurelien Gateau
  • Date: 2010-11-10 08:57:29 UTC
  • mto: This revision was merged to the branch mainline in revision 284.
  • Revision ID: aurelien.gateau@canonical.com-20101110085729-fl1ye7impkqhm0w6
Added a section about const correct-ness

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
 
 * This file is part of unity-2d
 
2
 * This file is part of unity-qt
3
3
 *
4
4
 * Copyright 2010 Canonical Ltd.
5
5
 *
6
6
 * Authors:
7
7
 * - Aurélien Gâteau <aurelien.gateau@canonical.com>
8
8
 *
9
 
 * This program is free software; you can redistribute it and/or modify
10
 
 * it under the terms of the GNU General Public License as published by
11
 
 * the Free Software Foundation; version 3.
12
 
 *
13
 
 * This program is distributed in the hope that it will be useful,
14
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 
 * GNU General Public License for more details.
17
 
 *
18
 
 * You should have received a copy of the GNU General Public License
19
 
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
9
 * License: GPL v3
20
10
 */
21
 
 
22
11
// Self
23
 
#include <menubarwidget.h>
 
12
#include "appmenuapplet.h"
24
13
 
25
14
// Local
26
 
#include <debug_p.h>
27
 
#include <indicatorentrywidget.h>
28
 
#include <indicatorsmanager.h>
 
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>
29
24
 
30
25
// Qt
31
26
#include <QHBoxLayout>
32
 
 
33
 
static const int MENU_ITEM_PADDING = 6;
34
 
 
35
 
MenuBarWidget::MenuBarWidget(IndicatorsManager* indicatorsManager, QWidget* parent)
36
 
: QWidget(parent)
37
 
, m_indicatorsManager(indicatorsManager)
38
 
, m_layout(new QHBoxLayout(this))
39
 
, m_isEmpty(true)
40
 
, m_isOpened(false)
41
 
{
42
 
    m_layout->setMargin(0);
43
 
    m_layout->setSpacing(0);
44
 
    indicatorsManager->indicators()->on_object_added.connect(
45
 
        sigc::mem_fun(this, &MenuBarWidget::onObjectAdded)
46
 
        );
47
 
    indicatorsManager->indicators()->on_object_removed.connect(
48
 
        sigc::mem_fun(this, &MenuBarWidget::onObjectRemoved)
49
 
        );
50
 
    indicatorsManager->indicators()->on_entry_activated.connect(
51
 
        sigc::mem_fun(this, &MenuBarWidget::onEntryActivated)
52
 
        );
53
 
    setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum);
54
 
    m_layout->addStretch();
55
 
}
56
 
 
57
 
MenuBarWidget::~MenuBarWidget()
58
 
{
59
 
    // disconnect from the entry signals
60
 
    entry_added.disconnect();
61
 
    entry_removed.disconnect();
62
 
    qDeleteAll(m_widgetList);
63
 
}
64
 
 
65
 
bool MenuBarWidget::isEmpty() const
66
 
{
67
 
    return m_isEmpty;
68
 
}
69
 
 
70
 
bool MenuBarWidget::isOpened() const
71
 
{
72
 
    return m_isOpened;
73
 
}
74
 
 
75
 
void MenuBarWidget::setOpened(bool opened)
76
 
{
77
 
    if (m_isOpened != opened) {
78
 
        m_isOpened = opened;
79
 
        isOpenedChanged();
80
 
    }
81
 
}
82
 
 
83
 
QList<IndicatorEntryWidget*> MenuBarWidget::entries() const
84
 
{
85
 
    return m_widgetList;
86
 
}
87
 
 
88
 
void MenuBarWidget::onObjectAdded(const unity::indicator::Indicator::Ptr& indicator)
89
 
{
90
 
    QString name = QString::fromStdString(indicator->name());
91
 
    if (name == "libappmenu.so") {
92
 
        m_indicator = indicator;
93
 
        entry_added = m_indicator->on_entry_added.connect(
94
 
                          sigc::mem_fun(this, &MenuBarWidget::onEntryAdded)
95
 
                      );
96
 
        entry_removed = m_indicator->on_entry_removed.connect(
97
 
                            sigc::mem_fun(this, &MenuBarWidget::onEntryRemoved)
98
 
                        );
99
 
    }
100
 
}
101
 
 
102
 
void MenuBarWidget::onObjectRemoved(const unity::indicator::Indicator::Ptr& indicator)
103
 
{
104
 
    QString name = QString::fromStdString(indicator->name());
105
 
    if (name == "libappmenu.so" && indicator.get()) {
106
 
        entry_added.disconnect();
107
 
        entry_removed.disconnect();
108
 
 
109
 
        Q_FOREACH(const unity::indicator::Entry::Ptr& entry, m_indicator->GetEntries())
110
 
        {
111
 
            onEntryRemoved (entry->id());
112
 
        }
113
 
 
114
 
        m_indicator.reset();
115
 
    }
116
 
}
117
 
 
118
 
void MenuBarWidget::onEntryAdded(const unity::indicator::Entry::Ptr& entry)
119
 
{
120
 
    IndicatorEntryWidget* widget = new IndicatorEntryWidget(entry);
121
 
    widget->setPadding(MENU_ITEM_PADDING);
122
 
    connect(widget, SIGNAL(isEmptyChanged()), SLOT(updateIsEmpty()));
123
 
 
124
 
    m_widgetList.append(widget);
125
 
    m_indicatorsManager->addIndicatorEntryWidget(widget);
126
 
 
127
 
    // Insert *before* stretch
128
 
    m_layout->insertWidget(m_layout->count() - 1, widget);
129
 
}
130
 
 
131
 
void MenuBarWidget::onEntryRemoved(const std::string& entry_id)
132
 
{
133
 
    Q_FOREACH(IndicatorEntryWidget* widget, m_widgetList)
134
 
    {
135
 
        if (widget->entry()->id() == entry_id) {
136
 
            disconnect(widget, SIGNAL(isEmptyChanged()));
137
 
            widget->hide();
138
 
            m_layout->removeWidget(widget);
139
 
            m_indicatorsManager->removeIndicatorEntryWidget(widget);
140
 
            m_widgetList.removeOne(widget);
141
 
            delete widget;
142
 
            updateIsEmpty();
143
 
            break;
144
 
        }
145
 
    }
146
 
}
147
 
 
148
 
void MenuBarWidget::updateIsEmpty()
149
 
{
150
 
    bool empty = true;
151
 
    Q_FOREACH(IndicatorEntryWidget* widget, m_widgetList) {
152
 
        if (!widget->isEmpty()) {
153
 
            empty = false;
154
 
            break;
155
 
        }
156
 
    }
157
 
    if (m_isEmpty != empty) {
158
 
        m_isEmpty = empty;
159
 
        isEmptyChanged();
160
 
    }
161
 
}
162
 
 
163
 
void MenuBarWidget::onEntryActivated(const std::string& id)
164
 
{
165
 
    bool isOpened = false;
166
 
    if (!id.empty()) {
167
 
        // We only cares about menubar entries
168
 
        Q_FOREACH(IndicatorEntryWidget* widget, m_widgetList) {
169
 
            if (widget->entry()->id() == id) {
170
 
                isOpened = true;
171
 
                break;
 
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* bamfWindow)
 
120
{
 
121
    WId id = bamfWindow ? bamfWindow->xid() : 0;
 
122
    if (id == m_activeWinId) {
 
123
        return;
 
124
    }
 
125
    if (id == window()->winId()) {
 
126
        // Do not update id if the active window is the one hosting this applet
 
127
        return;
 
128
    }
 
129
    m_activeWinId = id;
 
130
    updateMenuBar();
 
131
}
 
132
 
 
133
void AppMenuApplet::updateMenuBar()
 
134
{
 
135
    WId winId = m_activeWinId;
 
136
    QMenu* menu = menuForWinId(winId);
 
137
 
 
138
    if (!menu) {
 
139
        if (winId) {
 
140
            // We have an active window
 
141
            // FIXME: transient check
 
142
            /*
 
143
            WId mainWinId = KWindowSystem::transientFor(winId);
 
144
            if (mainWinId) {
 
145
                // We have a parent window, use a disabled version of its
 
146
                // menubar if it has one.
 
147
                QMenu* mainMenu = menuForWinId(mainWinId);
 
148
                if (mainMenu) {
 
149
                    mMenuCloner->setOriginalMenu(mainMenu);
 
150
                    menu = mMenuCloner->clonedMenu();
 
151
                }
 
152
            }*/
 
153
            // FIXME: WindowMenuManager
 
154
            /*
 
155
            if (!menu) {
 
156
                // No suitable menubar but we have a window, use the
 
157
                // generic window menu
 
158
                mWindowMenuManager->setWinId(winId);
 
159
                menu = mWindowMenu;
172
160
            }
173
 
        }
174
 
    }
175
 
    setOpened(isOpened);
176
 
}
177
 
 
178
 
#include "menubarwidget.moc"
 
161
            */
 
162
        } else {
 
163
            // No active window, show a desktop menubar
 
164
            // FIXME: Empty menu
 
165
            /*
 
166
            menu = mEmptyMenu;
 
167
            */
 
168
        }
 
169
    }
 
170
    fillMenuBar(menu);
 
171
}
 
172
 
 
173
void AppMenuApplet::fillMenuBar(QMenu* menu)
 
174
{
 
175
    m_menuBar->clear();
 
176
    // FIXME: Empty menu
 
177
    if (!menu) {
 
178
        return;
 
179
    }
 
180
    Q_FOREACH(QAction* action, menu->actions()) {
 
181
        if (action->isSeparator()) {
 
182
            continue;
 
183
        }
 
184
        m_menuBar->addAction(action);
 
185
    }
 
186
}
 
187
 
 
188
#include "appmenuapplet.moc"