mirror of
https://bitbucket.org/smil3y/kdelibs.git
synced 2025-02-24 02:42:48 +00:00
kdeui: implement sub-menu export/import for D-Bus menus
Signed-off-by: Ivailo Monev <xakepa10@gmail.com>
This commit is contained in:
parent
b54ba45a5a
commit
9a86368853
4 changed files with 89 additions and 31 deletions
|
@ -51,6 +51,7 @@ QDBusArgument& operator<<(QDBusArgument &argument, const KDBusMenuAction &kdbusm
|
||||||
argument << kdbusmenuaction.icondata;
|
argument << kdbusmenuaction.icondata;
|
||||||
argument << kdbusmenuaction.title;
|
argument << kdbusmenuaction.title;
|
||||||
argument << kdbusmenuaction.exclusive;
|
argument << kdbusmenuaction.exclusive;
|
||||||
|
argument << kdbusmenuaction.submenu;
|
||||||
argument.endStructure();
|
argument.endStructure();
|
||||||
return argument;
|
return argument;
|
||||||
}
|
}
|
||||||
|
@ -66,6 +67,7 @@ const QDBusArgument& operator>>(const QDBusArgument &argument, KDBusMenuAction &
|
||||||
argument >> kdbusmenuaction.icondata;
|
argument >> kdbusmenuaction.icondata;
|
||||||
argument >> kdbusmenuaction.title;
|
argument >> kdbusmenuaction.title;
|
||||||
argument >> kdbusmenuaction.exclusive;
|
argument >> kdbusmenuaction.exclusive;
|
||||||
|
argument >> kdbusmenuaction.submenu;
|
||||||
argument.endStructure();
|
argument.endStructure();
|
||||||
return argument;
|
return argument;
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,6 +61,7 @@ struct KDBusMenuAction
|
||||||
QByteArray icondata;
|
QByteArray icondata;
|
||||||
bool title;
|
bool title;
|
||||||
bool exclusive;
|
bool exclusive;
|
||||||
|
bool submenu;
|
||||||
};
|
};
|
||||||
Q_DECLARE_METATYPE(KDBusMenuAction);
|
Q_DECLARE_METATYPE(KDBusMenuAction);
|
||||||
Q_DECLARE_METATYPE(QList<KDBusMenuAction>);
|
Q_DECLARE_METATYPE(QList<KDBusMenuAction>);
|
||||||
|
|
|
@ -41,7 +41,7 @@ public Q_SLOTS:
|
||||||
|
|
||||||
KDBusMenu menu() const;
|
KDBusMenu menu() const;
|
||||||
|
|
||||||
QList<KDBusMenuAction> actions() const;
|
QList<KDBusMenuAction> actions(quint64 actionid = 0) const;
|
||||||
bool triggerAction(quint64 actionid) const;
|
bool triggerAction(quint64 actionid) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -107,21 +107,32 @@ KDBusMenu KDBusMenuAdaptor::menu() const
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<KDBusMenuAction> KDBusMenuAdaptor::actions() const
|
QList<KDBusMenuAction> KDBusMenuAdaptor::actions(quint64 actionid) const
|
||||||
{
|
{
|
||||||
QList<KDBusMenuAction> result;
|
QList<KDBusMenuAction> result;
|
||||||
if (m_menu.isNull()) {
|
if (m_menu.isNull()) {
|
||||||
kWarning(s_kdbusmenuarea) << "Menu is null";
|
kWarning(s_kdbusmenuarea) << "Menu is null";
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
foreach (QAction* action, m_menu->actions()) {
|
QList<QAction*> actionslist;
|
||||||
|
if (actionid == 0) {
|
||||||
|
actionslist = m_menu->actions();
|
||||||
|
} else {
|
||||||
|
foreach (const QAction* action, m_menu->actions()) {
|
||||||
|
const quint64 itactionid = kDBusMenuActionID(action);
|
||||||
|
if (actionid == itactionid) {
|
||||||
|
const QMenu* actionmenu = action->menu();
|
||||||
|
if (!actionmenu) {
|
||||||
|
kWarning(s_kdbusmenuarea) << "Requested actions for non-menu action" << actionid;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
actionslist = actionmenu->actions();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
foreach (QAction* action, actionslist) {
|
||||||
const quint64 actionid = kDBusMenuActionID(action);
|
const quint64 actionid = kDBusMenuActionID(action);
|
||||||
kDebug(s_kdbusmenuarea) << "Exporting action" << actionid;
|
kDebug(s_kdbusmenuarea) << "Exporting action" << actionid;
|
||||||
const QMenu* actionmenu = action->menu();
|
|
||||||
if (actionmenu) {
|
|
||||||
kWarning(s_kdbusmenuarea) << "Menu actions are not supported";
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
KDBusMenuAction actionproperties;
|
KDBusMenuAction actionproperties;
|
||||||
// see kdeui/widgets/kmenu.cpp
|
// see kdeui/widgets/kmenu.cpp
|
||||||
actionproperties.title = (action->objectName() == QLatin1String("kmenu_title"));
|
actionproperties.title = (action->objectName() == QLatin1String("kmenu_title"));
|
||||||
|
@ -170,6 +181,8 @@ QList<KDBusMenuAction> KDBusMenuAdaptor::actions() const
|
||||||
}
|
}
|
||||||
const QActionGroup* actiongroup = action->actionGroup();
|
const QActionGroup* actiongroup = action->actionGroup();
|
||||||
actionproperties.exclusive = (actiongroup && actiongroup->isExclusive());
|
actionproperties.exclusive = (actiongroup && actiongroup->isExclusive());
|
||||||
|
const QMenu* actionmenu = action->menu();
|
||||||
|
actionproperties.submenu = (actionmenu != nullptr);
|
||||||
result.append(actionproperties);
|
result.append(actionproperties);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
@ -183,10 +196,19 @@ bool KDBusMenuAdaptor::triggerAction(quint64 actionid) const
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
foreach (QAction* action, m_menu->actions()) {
|
foreach (QAction* action, m_menu->actions()) {
|
||||||
const quint64 itactionid = kDBusMenuActionID(action);
|
quint64 itactionid = kDBusMenuActionID(action);
|
||||||
if (itactionid == actionid) {
|
if (itactionid == actionid) {
|
||||||
return QMetaObject::invokeMethod(action, "triggered");
|
return QMetaObject::invokeMethod(action, "triggered");
|
||||||
}
|
}
|
||||||
|
const QMenu* actionmenu = action->menu();
|
||||||
|
if (actionmenu) {
|
||||||
|
foreach (QAction* subaction, actionmenu->actions()) {
|
||||||
|
itactionid = kDBusMenuActionID(subaction);
|
||||||
|
if (itactionid == actionid) {
|
||||||
|
return QMetaObject::invokeMethod(subaction, "triggered");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
kWarning(s_kdbusmenuarea) << "Could not find action for" << actionid;
|
kWarning(s_kdbusmenuarea) << "Could not find action for" << actionid;
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -32,6 +32,8 @@ class KDBusMenuImporterPrivate
|
||||||
public:
|
public:
|
||||||
KDBusMenuImporterPrivate();
|
KDBusMenuImporterPrivate();
|
||||||
|
|
||||||
|
static QAction* createAction(QMenu *menu, const KDBusMenuAction &actionproperties);
|
||||||
|
|
||||||
QDBusInterface* interface;
|
QDBusInterface* interface;
|
||||||
QMenu* menu;
|
QMenu* menu;
|
||||||
};
|
};
|
||||||
|
@ -42,6 +44,31 @@ KDBusMenuImporterPrivate::KDBusMenuImporterPrivate()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QAction* KDBusMenuImporterPrivate::createAction(QMenu *menu, const KDBusMenuAction &actionproperties)
|
||||||
|
{
|
||||||
|
QAction* action = new QAction(menu);
|
||||||
|
action->setText(actionproperties.text);
|
||||||
|
action->setToolTip(actionproperties.tooltip);
|
||||||
|
action->setStatusTip(actionproperties.statustip);
|
||||||
|
action->setWhatsThis(actionproperties.whatsthis);
|
||||||
|
action->setSeparator(actionproperties.separator);
|
||||||
|
action->setCheckable(actionproperties.checkable);
|
||||||
|
action->setChecked(actionproperties.checked);
|
||||||
|
action->setEnabled(actionproperties.enabled);
|
||||||
|
action->setVisible(actionproperties.visible);
|
||||||
|
QList<QKeySequence> shortcuts;
|
||||||
|
foreach (const QString &keysequence, actionproperties.shortcuts) {
|
||||||
|
shortcuts.append(QKeySequence::fromString(keysequence));
|
||||||
|
}
|
||||||
|
action->setShortcuts(shortcuts);
|
||||||
|
if (actionproperties.exclusive) {
|
||||||
|
QActionGroup *actiongroup = new QActionGroup(action);
|
||||||
|
actiongroup->addAction(action);
|
||||||
|
}
|
||||||
|
action->setData(QVariant(actionproperties.id));
|
||||||
|
return action;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
KDBusMenuImporter::KDBusMenuImporter(const QString &service, const QString &path, QObject *parent)
|
KDBusMenuImporter::KDBusMenuImporter(const QString &service, const QString &path, QObject *parent)
|
||||||
: QObject(parent),
|
: QObject(parent),
|
||||||
|
@ -107,7 +134,7 @@ void KDBusMenuImporter::updateMenu()
|
||||||
QPixmap actionpixmap;
|
QPixmap actionpixmap;
|
||||||
const bool pixmaploaded = actionpixmap.loadFromData(actionproperties.icondata, s_kdbusmenuiconformat);
|
const bool pixmaploaded = actionpixmap.loadFromData(actionproperties.icondata, s_kdbusmenuiconformat);
|
||||||
if (!pixmaploaded) {
|
if (!pixmaploaded) {
|
||||||
kWarning(s_kdbusmenuarea) << "Could not load icon pixmap" << actionid;
|
kWarning(s_kdbusmenuarea) << "Could not load action icon pixmap" << actionid;
|
||||||
} else {
|
} else {
|
||||||
actionicon = QIcon(actionpixmap);
|
actionicon = QIcon(actionpixmap);
|
||||||
}
|
}
|
||||||
|
@ -117,28 +144,34 @@ void KDBusMenuImporter::updateMenu()
|
||||||
// see kdeui/widgets/kmenu.cpp
|
// see kdeui/widgets/kmenu.cpp
|
||||||
action = KMenu::titleAction(actionicon, actionproperties.text, d->menu);
|
action = KMenu::titleAction(actionicon, actionproperties.text, d->menu);
|
||||||
} else {
|
} else {
|
||||||
action = new QAction(d->menu);
|
action = KDBusMenuImporterPrivate::createAction(d->menu, actionproperties);
|
||||||
action->setText(actionproperties.text);
|
}
|
||||||
|
if (actionproperties.submenu) {
|
||||||
|
QDBusReply<QList<KDBusMenuAction>> subactionsreply = d->interface->call("actions", actionid);
|
||||||
|
if (!subactionsreply.isValid()) {
|
||||||
|
kWarning(s_kdbusmenuarea) << "Invalid sub-actions reply" << subactionsreply.error();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
QMenu* subactionmenu = KDBusMenuImporter::createMenu(d->menu);
|
||||||
|
foreach (const KDBusMenuAction &subactionproperties, subactionsreply.value()) {
|
||||||
|
QIcon subactionicon = KDBusMenuImporter::iconForName(subactionproperties.icon);
|
||||||
|
if (subactionicon.isNull() && !subactionproperties.icondata.isEmpty()) {
|
||||||
|
QPixmap subactionpixmap;
|
||||||
|
const bool subpixmaploaded = subactionpixmap.loadFromData(subactionproperties.icondata, s_kdbusmenuiconformat);
|
||||||
|
if (!subpixmaploaded) {
|
||||||
|
kWarning(s_kdbusmenuarea) << "Could not load sub-action icon pixmap" << actionid;
|
||||||
|
} else {
|
||||||
|
subactionicon = QIcon(subactionpixmap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
QAction* subaction = KDBusMenuImporterPrivate::createAction(subactionmenu, subactionproperties);
|
||||||
|
subaction->setIcon(subactionicon);
|
||||||
|
connect(subaction, SIGNAL(triggered()), this, SLOT(slotActionTriggered()));
|
||||||
|
subactionmenu->addAction(subaction);
|
||||||
|
}
|
||||||
|
action->setMenu(subactionmenu);
|
||||||
|
}
|
||||||
action->setIcon(actionicon);
|
action->setIcon(actionicon);
|
||||||
action->setToolTip(actionproperties.tooltip);
|
|
||||||
action->setStatusTip(actionproperties.statustip);
|
|
||||||
action->setWhatsThis(actionproperties.whatsthis);
|
|
||||||
action->setSeparator(actionproperties.separator);
|
|
||||||
action->setCheckable(actionproperties.checkable);
|
|
||||||
action->setChecked(actionproperties.checked);
|
|
||||||
action->setEnabled(actionproperties.enabled);
|
|
||||||
action->setVisible(actionproperties.visible);
|
|
||||||
QList<QKeySequence> shortcuts;
|
|
||||||
foreach (const QString &keysequence, actionproperties.shortcuts) {
|
|
||||||
shortcuts.append(QKeySequence::fromString(keysequence));
|
|
||||||
}
|
|
||||||
action->setShortcuts(shortcuts);
|
|
||||||
if (actionproperties.exclusive) {
|
|
||||||
QActionGroup *actiongroup = new QActionGroup(action);
|
|
||||||
actiongroup->addAction(action);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
action->setData(QVariant(actionid));
|
|
||||||
connect(action, SIGNAL(triggered()), this, SLOT(slotActionTriggered()));
|
connect(action, SIGNAL(triggered()), this, SLOT(slotActionTriggered()));
|
||||||
d->menu->addAction(action);
|
d->menu->addAction(action);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue