2
* Copyright (C) 2016 Canonical, Ltd.
4
* This program is free software: you can redistribute it and/or modify it under
5
* the terms of the GNU Lesser General Public License version 3, as published by
6
* the Free Software Foundation.
8
* This program is distributed in the hope that it will be useful, but WITHOUT
9
* ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
10
* SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11
* 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/>.
18
#include "gmenumodelplatformmenu.h"
19
#include "gmenumodelexporter.h"
21
#include "menuregistrar.h"
27
#include <QCoreApplication>
29
#define BAR_DEBUG_MSG qCDebug(ubuntuappmenu).nospace() << "UbuntuPlatformMenuBar[" << (void*)this <<"]::" << __func__
30
#define MENU_DEBUG_MSG qCDebug(ubuntuappmenu).nospace() << "UbuntuPlatformMenu[" << (void*)this <<"]::" << __func__
31
#define ITEM_DEBUG_MSG qCDebug(ubuntuappmenu).nospace() << "UbuntuPlatformMenuItem[" << (void*)this <<"]::" << __func__
39
QDebug operator<<(QDebug stream, UbuntuPlatformMenuBar* bar) {
40
if (bar) return bar->operator<<(stream);
43
QDebug operator<<(QDebug stream, UbuntuPlatformMenu* menu) {
44
if (menu) return menu->operator<<(stream);
47
QDebug operator<<(QDebug stream, UbuntuPlatformMenuItem* menuItem) {
48
if (menuItem) return menuItem->operator<<(stream);
52
UbuntuPlatformMenuBar::UbuntuPlatformMenuBar()
53
: m_exporter(new UbuntuMenuBarExporter(this))
54
, m_registrar(new UbuntuMenuRegistrar())
57
BAR_DEBUG_MSG << "()";
59
connect(this, &UbuntuPlatformMenuBar::menuInserted, this, &UbuntuPlatformMenuBar::structureChanged);
60
connect(this,&UbuntuPlatformMenuBar::menuRemoved, this, &UbuntuPlatformMenuBar::structureChanged);
63
UbuntuPlatformMenuBar::~UbuntuPlatformMenuBar()
65
BAR_DEBUG_MSG << "()";
68
void UbuntuPlatformMenuBar::insertMenu(QPlatformMenu *menu, QPlatformMenu *before)
70
BAR_DEBUG_MSG << "(menu=" << menu << ", before=" << before << ")";
72
if (m_menus.contains(menu)) return;
75
m_menus.push_back(menu);
77
for (auto iter = m_menus.begin(); iter != m_menus.end(); ++iter) {
78
if (*iter == before) {
79
m_menus.insert(iter, menu);
84
connect(static_cast<UbuntuPlatformMenu*>(menu), &UbuntuPlatformMenu::structureChanged,
85
this, &UbuntuPlatformMenuBar::structureChanged);
86
Q_EMIT menuInserted(menu);
89
void UbuntuPlatformMenuBar::removeMenu(QPlatformMenu *menu)
91
BAR_DEBUG_MSG << "(menu=" << menu << ")";
93
QMutableListIterator<QPlatformMenu*> iterator(m_menus);
94
while(iterator.hasNext()) {
95
if (iterator.next() == menu) {
100
disconnect(static_cast<UbuntuPlatformMenu*>(menu), &UbuntuPlatformMenu::structureChanged,
101
this, &UbuntuPlatformMenuBar::structureChanged);
102
Q_EMIT menuRemoved(menu);
105
void UbuntuPlatformMenuBar::syncMenu(QPlatformMenu *menu)
107
BAR_DEBUG_MSG << "(menu=" << menu << ")";
112
void UbuntuPlatformMenuBar::handleReparent(QWindow *parentWindow)
114
BAR_DEBUG_MSG << "(parentWindow=" << parentWindow << ")";
117
m_registrar->registerMenuForWindow(parentWindow, QDBusObjectPath(m_exporter->menuPath()));
120
QPlatformMenu *UbuntuPlatformMenuBar::menuForTag(quintptr tag) const
122
Q_FOREACH(QPlatformMenu* menu, m_menus) {
123
if (menu->tag() == tag) {
130
const QList<QPlatformMenu *> UbuntuPlatformMenuBar::menus() const
135
QDebug UbuntuPlatformMenuBar::operator<<(QDebug stream)
137
stream.nospace().noquote() << QString("%1").arg("", logRecusion, QLatin1Char('\t'))
138
<< "UbuntuPlatformMenuBar(this=" << (void*)this << ")" << endl;
139
Q_FOREACH(QPlatformMenu* menu, m_menus) {
140
auto myMenu = static_cast<UbuntuPlatformMenu*>(menu);
151
#if QT_VERSION >= QT_VERSION_CHECK(5, 6, 0)
152
QPlatformMenu *UbuntuPlatformMenuBar::createMenu() const
154
return new UbuntuPlatformMenu();
158
void UbuntuPlatformMenuBar::setReady(bool isReady)
160
if (m_ready != isReady) {
166
//////////////////////////////////////////////////////////////
168
UbuntuPlatformMenu::UbuntuPlatformMenu()
169
: m_parentWindow(nullptr)
170
, m_exporter(nullptr)
171
, m_registrar(nullptr)
173
MENU_DEBUG_MSG << "()";
175
connect(this, &UbuntuPlatformMenu::menuItemInserted, this, &UbuntuPlatformMenu::structureChanged);
176
connect(this, &UbuntuPlatformMenu::menuItemRemoved, this, &UbuntuPlatformMenu::structureChanged);
179
UbuntuPlatformMenu::~UbuntuPlatformMenu()
181
MENU_DEBUG_MSG << "()";
184
void UbuntuPlatformMenu::insertMenuItem(QPlatformMenuItem *menuItem, QPlatformMenuItem *before)
186
MENU_DEBUG_MSG << "(menuItem=" << menuItem << ", before=" << before << ")";
188
if (m_menuItems.contains(menuItem)) return;
191
m_menuItems.push_back(menuItem);
193
for (auto iter = m_menuItems.begin(); iter != m_menuItems.end(); ++iter) {
194
if (*iter == before) {
195
m_menuItems.insert(iter, menuItem);
201
Q_EMIT menuItemInserted(menuItem);
204
void UbuntuPlatformMenu::removeMenuItem(QPlatformMenuItem *menuItem)
206
MENU_DEBUG_MSG << "(menuItem=" << menuItem << ")";
208
QMutableListIterator<QPlatformMenuItem*> iterator(m_menuItems);
209
while(iterator.hasNext()) {
210
if (iterator.next() == menuItem) {
215
Q_EMIT menuItemRemoved(menuItem);
218
void UbuntuPlatformMenu::syncMenuItem(QPlatformMenuItem *menuItem)
220
MENU_DEBUG_MSG << "(menuItem=" << menuItem << ")";
225
void UbuntuPlatformMenu::syncSeparatorsCollapsible(bool enable)
227
MENU_DEBUG_MSG << "(enable=" << enable << ")";
231
void UbuntuPlatformMenu::setTag(quintptr tag)
233
MENU_DEBUG_MSG << "(tag=" << tag << ")";
237
quintptr UbuntuPlatformMenu::tag() const
242
void UbuntuPlatformMenu::setText(const QString &text)
244
MENU_DEBUG_MSG << "(text=" << text << ")";
245
if (m_text != text) {
247
Q_EMIT propertyChanged();
251
void UbuntuPlatformMenu::setIcon(const QIcon &icon)
253
MENU_DEBUG_MSG << "(icon=" << icon.name() << ")";
255
if (!icon.isNull() || (!m_icon.isNull() && icon.isNull())) {
257
Q_EMIT propertyChanged();
261
void UbuntuPlatformMenu::setEnabled(bool enabled)
263
MENU_DEBUG_MSG << "(enabled=" << enabled << ")";
265
if (m_enabled != enabled) {
267
Q_EMIT propertyChanged();
271
void UbuntuPlatformMenu::setVisible(bool isVisible)
273
MENU_DEBUG_MSG << "(visible=" << isVisible << ")";
275
if (m_visible != isVisible) {
276
m_visible = isVisible;
277
Q_EMIT propertyChanged();
281
void UbuntuPlatformMenu::setMinimumWidth(int width)
283
MENU_DEBUG_MSG << "(width=" << width << ")";
288
void UbuntuPlatformMenu::setFont(const QFont &font)
290
MENU_DEBUG_MSG << "(font=" << font << ")";
295
void UbuntuPlatformMenu::showPopup(const QWindow *parentWindow, const QRect &targetRect, const QPlatformMenuItem *item)
297
MENU_DEBUG_MSG << "(parentWindow=" << parentWindow << ", targetRect=" << targetRect << ", item=" << item << ")";
300
m_exporter.reset(new UbuntuMenuExporter(this));
301
m_exporter->exportModels();
304
if (parentWindow != m_parentWindow) {
305
if (m_parentWindow) {
306
m_registrar->unregisterMenu();
309
m_parentWindow = parentWindow;
311
if (m_parentWindow) {
312
if (!m_registrar) m_registrar.reset(new UbuntuMenuRegistrar);
313
m_registrar->registerMenuForWindow(const_cast<QWindow*>(m_parentWindow),
314
QDBusObjectPath(m_exporter->menuPath()));
318
Q_UNUSED(targetRect);
323
void UbuntuPlatformMenu::dismiss()
325
MENU_DEBUG_MSG << "()";
327
if (m_registrar) { m_registrar->unregisterMenu(); }
328
if (m_exporter) { m_exporter->unexportModels(); }
331
QPlatformMenuItem *UbuntuPlatformMenu::menuItemAt(int position) const
333
if (position < 0 || position >= m_menuItems.count()) return nullptr;
334
return m_menuItems.at(position);
337
QPlatformMenuItem *UbuntuPlatformMenu::menuItemForTag(quintptr tag) const
339
Q_FOREACH(QPlatformMenuItem* menuItem, m_menuItems) {
340
if (menuItem->tag() == tag) {
347
QPlatformMenuItem *UbuntuPlatformMenu::createMenuItem() const
349
return new UbuntuPlatformMenuItem();
352
#if QT_VERSION >= QT_VERSION_CHECK(5, 6, 0)
353
QPlatformMenu *UbuntuPlatformMenu::createSubMenu() const
355
return new UbuntuPlatformMenu();
359
const QList<QPlatformMenuItem *> UbuntuPlatformMenu::menuItems() const
364
QDebug UbuntuPlatformMenu::operator<<(QDebug stream)
366
stream.nospace().noquote() << QString("%1").arg("", logRecusion, QLatin1Char('\t'))
367
<< "UbuntuPlatformMenu(this=" << (void*)this << ", text=\"" << m_text << "\")" << endl;
368
Q_FOREACH(QPlatformMenuItem* item, m_menuItems) {
370
auto myItem = static_cast<UbuntuPlatformMenuItem*>(item);
379
//////////////////////////////////////////////////////////////
381
UbuntuPlatformMenuItem::UbuntuPlatformMenuItem()
384
ITEM_DEBUG_MSG << "()";
387
UbuntuPlatformMenuItem::~UbuntuPlatformMenuItem()
389
ITEM_DEBUG_MSG << "()";
392
void UbuntuPlatformMenuItem::setTag(quintptr tag)
394
ITEM_DEBUG_MSG << "(tag=" << tag << ")";
398
quintptr UbuntuPlatformMenuItem::tag() const
403
void UbuntuPlatformMenuItem::setText(const QString &text)
405
ITEM_DEBUG_MSG << "(text=" << text << ")";
406
if (m_text != text) {
408
Q_EMIT propertyChanged();
412
void UbuntuPlatformMenuItem::setIcon(const QIcon &icon)
414
ITEM_DEBUG_MSG << "(icon=" << icon.name() << ")";
416
if (!icon.isNull() || (!m_icon.isNull() && icon.isNull())) {
418
Q_EMIT propertyChanged();
422
void UbuntuPlatformMenuItem::setVisible(bool isVisible)
424
ITEM_DEBUG_MSG << "(visible=" << isVisible << ")";
425
if (m_visible != isVisible) {
426
m_visible = isVisible;
427
Q_EMIT propertyChanged();
431
void UbuntuPlatformMenuItem::setIsSeparator(bool isSeparator)
433
ITEM_DEBUG_MSG << "(separator=" << isSeparator << ")";
434
if (m_separator != isSeparator) {
435
m_separator = isSeparator;
436
Q_EMIT propertyChanged();
440
void UbuntuPlatformMenuItem::setFont(const QFont &font)
442
ITEM_DEBUG_MSG << "(font=" << font << ")";
446
void UbuntuPlatformMenuItem::setRole(QPlatformMenuItem::MenuRole role)
448
ITEM_DEBUG_MSG << "(role=" << role << ")";
452
void UbuntuPlatformMenuItem::setCheckable(bool checkable)
454
ITEM_DEBUG_MSG << "(checkable=" << checkable << ")";
455
if (m_checkable != checkable) {
456
m_checkable = checkable;
457
Q_EMIT propertyChanged();
461
void UbuntuPlatformMenuItem::setChecked(bool isChecked)
463
ITEM_DEBUG_MSG << "(checked=" << isChecked << ")";
464
if (m_checked != isChecked) {
465
m_checked = isChecked;
466
Q_EMIT checkedChanged(isChecked);
467
Q_EMIT propertyChanged();
471
void UbuntuPlatformMenuItem::setShortcut(const QKeySequence &shortcut)
473
ITEM_DEBUG_MSG << "(shortcut=" << shortcut << ")";
474
if (m_shortcut != shortcut) {
475
m_shortcut = shortcut;
476
Q_EMIT propertyChanged();
480
void UbuntuPlatformMenuItem::setEnabled(bool enabled)
482
ITEM_DEBUG_MSG << "(enabled=" << enabled << ")";
483
if (m_enabled != enabled) {
485
Q_EMIT enabledChanged(enabled);
486
Q_EMIT propertyChanged();
490
void UbuntuPlatformMenuItem::setIconSize(int size)
492
ITEM_DEBUG_MSG << "(size=" << size << ")";
496
void UbuntuPlatformMenuItem::setMenu(QPlatformMenu *menu)
498
ITEM_DEBUG_MSG << "(menu=" << menu << ")";
499
if (m_menu != menu) {
501
Q_EMIT propertyChanged();
505
QPlatformMenu *UbuntuPlatformMenuItem::menu() const
510
QDebug UbuntuPlatformMenuItem::operator<<(QDebug stream)
512
QString properties = "text=\"" + m_text + "\"";
514
stream.nospace().noquote() << QString("%1").arg("", logRecusion, QLatin1Char('\t'))
515
<< "UbuntuPlatformMenuItem(this=" << (void*)this << ", "
516
<< (m_separator ? "Separator" : properties) << ")" << endl;
518
auto myMenu = static_cast<UbuntuPlatformMenu*>(m_menu);