File indexing completed on 2024-04-21 05:31:18

0001 /*
0002     SPDX-FileCopyrightText: 2018 Michail Vourlakos <mvourlakos@gmail.com>
0003     SPDX-License-Identifier: GPL-2.0-or-later
0004 */
0005 
0006 #include "menu.h"
0007 
0008 // local
0009 #include "contextmenudata.h"
0010 #include "layoutmenuitemwidget.h"
0011 
0012 // Qt
0013 #include <QAction>
0014 #include <QDebug>
0015 #include <QFont>
0016 #include <QMenu>
0017 #include <QtDBus>
0018 #include <QTimer>
0019 #include <QLatin1String>
0020 
0021 // KDE
0022 #include <KActionCollection>
0023 #include <KLocalizedString>
0024 
0025 // Plasma
0026 #include <Plasma/Containment>
0027 #include <Plasma/Corona>
0028 #include <Plasma/ServiceJob>
0029 
0030 const int MEMORYINDEX = 0;
0031 const int ACTIVELAYOUTSINDEX = 1;
0032 const int CURRENTLAYOUTSINDEX = 2;
0033 const int ACTIONSALWAYSSHOWN = 3;
0034 const int LAYOUTMENUINDEX = 4;
0035 const int VIEWLAYOUTINDEX = 5;
0036 const int VIEWTYPEINDEX = 6;
0037 
0038 enum LayoutsMemoryUsage
0039 {
0040     SingleLayout = 0,
0041     MultipleLayouts
0042 };
0043 
0044 enum LatteConfigPage
0045 {
0046     LayoutPage = 0,
0047     PreferencesPage
0048 };
0049 
0050 Menu::Menu(QObject *parent, const QVariantList &args)
0051     : Plasma::ContainmentActions(parent, args)
0052 {
0053 }
0054 
0055 Menu::~Menu()
0056 {
0057     //! sub-menus
0058     m_addViewMenu->deleteLater();
0059     m_switchLayoutsMenu->deleteLater();
0060     m_moveToLayoutMenu->deleteLater();
0061 
0062     //! clear menu actions that have been created from submenus
0063     m_actions.remove(Latte::Data::ContextMenu::ADDVIEWACTION);
0064     m_actions.remove(Latte::Data::ContextMenu::LAYOUTSACTION);
0065 
0066     //! actions
0067     qDeleteAll(m_actions.values());
0068     m_actions.clear();
0069 }
0070 
0071 void Menu::restore(const KConfigGroup &config)
0072 {
0073     if (!m_actions.isEmpty()) {
0074         return;
0075     }
0076 
0077     m_actions[Latte::Data::ContextMenu::SECTIONACTION] = new QAction(this);
0078     m_actions[Latte::Data::ContextMenu::SECTIONACTION]->setSeparator(true);
0079     m_actions[Latte::Data::ContextMenu::SECTIONACTION]->setText("Latte");
0080 
0081     m_actions[Latte::Data::ContextMenu::SEPARATOR1ACTION] = new QAction(this);
0082     m_actions[Latte::Data::ContextMenu::SEPARATOR1ACTION]->setSeparator(true);
0083 
0084     //! Print Message...
0085     m_actions[Latte::Data::ContextMenu::PRINTACTION] = new QAction(QIcon::fromTheme("edit"), "Print Message...", this);
0086     connect(m_actions[Latte::Data::ContextMenu::PRINTACTION], &QAction::triggered, [ = ]() {
0087         qDebug() << "Action Trigerred !!!";
0088     });
0089 
0090     //! Add Widgets...
0091     m_actions[Latte::Data::ContextMenu::ADDWIDGETSACTION] = new QAction(QIcon::fromTheme("list-add"), i18n("&Add Widgets..."), this);
0092     m_actions[Latte::Data::ContextMenu::ADDWIDGETSACTION]->setStatusTip(i18n("Show Widget Explorer"));
0093     connect(m_actions[Latte::Data::ContextMenu::ADDWIDGETSACTION], &QAction::triggered, this, &Menu::requestWidgetExplorer);
0094     this->containment()->actions()->addAction(Latte::Data::ContextMenu::ADDWIDGETSACTION, m_actions[Latte::Data::ContextMenu::ADDWIDGETSACTION]);
0095 
0096     /*connect(m_addWidgetsAction, &QAction::triggered, [ = ]() {
0097         QDBusInterface iface("org.kde.plasmashell", "/PlasmaShell", "", QDBusConnection::sessionBus());
0098 
0099         if (iface.isValid()) {
0100             iface.call("toggleWidgetExplorer");
0101         }
0102     });*/
0103 
0104     //! Edit Dock/Panel...
0105     m_actions[Latte::Data::ContextMenu::EDITVIEWACTION] = new QAction(QIcon::fromTheme("document-edit"), "Edit Dock...", this);
0106     connect(m_actions[Latte::Data::ContextMenu::EDITVIEWACTION], &QAction::triggered, this, &Menu::requestConfiguration);
0107     this->containment()->actions()->addAction(Latte::Data::ContextMenu::EDITVIEWACTION, m_actions[Latte::Data::ContextMenu::EDITVIEWACTION]);
0108 
0109 
0110     //! Quit Application
0111     m_actions[Latte::Data::ContextMenu::QUITLATTEACTION] = new QAction(QIcon::fromTheme("application-exit"), i18nc("quit application", "Quit &Latte"));
0112     connect(m_actions[Latte::Data::ContextMenu::QUITLATTEACTION], &QAction::triggered, this, &Menu::quitApplication);
0113     this->containment()->actions()->addAction(Latte::Data::ContextMenu::QUITLATTEACTION, m_actions[Latte::Data::ContextMenu::QUITLATTEACTION]);
0114 
0115     //! Layouts submenu
0116     m_switchLayoutsMenu = new QMenu;
0117     m_actions[Latte::Data::ContextMenu::LAYOUTSACTION] = m_switchLayoutsMenu->menuAction();
0118     m_actions[Latte::Data::ContextMenu::LAYOUTSACTION]->setText(i18n("&Layouts"));
0119     m_actions[Latte::Data::ContextMenu::LAYOUTSACTION]->setIcon(QIcon::fromTheme("user-identity"));
0120     m_actions[Latte::Data::ContextMenu::LAYOUTSACTION]->setStatusTip(i18n("Switch to another layout"));
0121     this->containment()->actions()->addAction(Latte::Data::ContextMenu::LAYOUTSACTION, m_actions[Latte::Data::ContextMenu::LAYOUTSACTION]);
0122 
0123     connect(m_switchLayoutsMenu, &QMenu::aboutToShow, this, &Menu::populateLayouts);
0124     connect(m_switchLayoutsMenu, &QMenu::triggered, this, &Menu::switchToLayout);
0125 
0126     //! Add View submenu
0127     m_addViewMenu = new QMenu;
0128     m_actions[Latte::Data::ContextMenu::ADDVIEWACTION] = m_addViewMenu->menuAction();
0129     m_actions[Latte::Data::ContextMenu::ADDVIEWACTION]->setText(i18n("&Add Dock/Panel"));
0130     m_actions[Latte::Data::ContextMenu::ADDVIEWACTION]->setIcon(QIcon::fromTheme("list-add"));
0131     m_actions[Latte::Data::ContextMenu::ADDVIEWACTION]->setStatusTip(i18n("Add dock or panel based on specific template"));
0132     this->containment()->actions()->addAction(Latte::Data::ContextMenu::ADDVIEWACTION, m_actions[Latte::Data::ContextMenu::ADDVIEWACTION]);
0133 
0134     connect(m_addViewMenu, &QMenu::aboutToShow, this, &Menu::populateViewTemplates);
0135     connect(m_addViewMenu, &QMenu::triggered, this, &Menu::addView);
0136 
0137     //! Move submenu
0138     m_moveToLayoutMenu = new QMenu;
0139     m_actions[Latte::Data::ContextMenu::MOVEVIEWACTION] = m_moveToLayoutMenu->menuAction();
0140     m_actions[Latte::Data::ContextMenu::MOVEVIEWACTION]->setText("Move To Layout");
0141     m_actions[Latte::Data::ContextMenu::MOVEVIEWACTION]->setIcon(QIcon::fromTheme("transform-move-horizontal"));
0142     m_actions[Latte::Data::ContextMenu::MOVEVIEWACTION]->setStatusTip(i18n("Move dock or panel to different layout"));
0143     this->containment()->actions()->addAction(Latte::Data::ContextMenu::MOVEVIEWACTION, m_actions[Latte::Data::ContextMenu::MOVEVIEWACTION]);
0144 
0145     connect(m_moveToLayoutMenu, &QMenu::aboutToShow, this, &Menu::populateMoveToLayouts);
0146     connect(m_moveToLayoutMenu, &QMenu::triggered, this, &Menu::moveToLayout);
0147 
0148     //! Configure Latte
0149     m_actions[Latte::Data::ContextMenu::PREFERENCESACTION] = new QAction(QIcon::fromTheme("configure"), i18nc("global settings window", "&Configure Latte..."), this);
0150     this->containment()->actions()->addAction(Latte::Data::ContextMenu::PREFERENCESACTION, m_actions[Latte::Data::ContextMenu::PREFERENCESACTION]);
0151     connect(m_actions[Latte::Data::ContextMenu::PREFERENCESACTION], &QAction::triggered, [=](){
0152         QDBusInterface iface("org.kde.lattedock", "/Latte", "", QDBusConnection::sessionBus());
0153 
0154         if (iface.isValid()) {
0155             iface.call("showSettingsWindow", (int)PreferencesPage);
0156         }
0157     });
0158 
0159     //! Duplicate Action
0160     m_actions[Latte::Data::ContextMenu::DUPLICATEVIEWACTION] = new QAction(QIcon::fromTheme("edit-copy"), "Duplicate Dock as Template", this);
0161     connect(m_actions[Latte::Data::ContextMenu::DUPLICATEVIEWACTION], &QAction::triggered, [=](){
0162         QDBusInterface iface("org.kde.lattedock", "/Latte", "", QDBusConnection::sessionBus());
0163 
0164         if (iface.isValid()) {
0165             iface.call("duplicateView", containment()->id());
0166         }
0167     });
0168     this->containment()->actions()->addAction(Latte::Data::ContextMenu::DUPLICATEVIEWACTION, m_actions[Latte::Data::ContextMenu::DUPLICATEVIEWACTION]);
0169 
0170     //! Export View Template Action
0171     m_actions[Latte::Data::ContextMenu::EXPORTVIEWTEMPLATEACTION] = new QAction(QIcon::fromTheme("document-export"), "Export as Template...", this);
0172     connect(m_actions[Latte::Data::ContextMenu::EXPORTVIEWTEMPLATEACTION], &QAction::triggered, [=](){
0173         QDBusInterface iface("org.kde.lattedock", "/Latte", "", QDBusConnection::sessionBus());
0174 
0175         if (iface.isValid()) {
0176             iface.call("exportViewTemplate", containment()->id());
0177         }
0178     });
0179     this->containment()->actions()->addAction(Latte::Data::ContextMenu::EXPORTVIEWTEMPLATEACTION, m_actions[Latte::Data::ContextMenu::EXPORTVIEWTEMPLATEACTION]);
0180 
0181     //! Remove Action
0182     m_actions[Latte::Data::ContextMenu::REMOVEVIEWACTION] = new QAction(QIcon::fromTheme("delete"), "Remove Dock", this);
0183     connect(m_actions[Latte::Data::ContextMenu::REMOVEVIEWACTION], &QAction::triggered, [=](){
0184         QDBusInterface iface("org.kde.lattedock", "/Latte", "", QDBusConnection::sessionBus());
0185 
0186         if (iface.isValid()) {
0187             iface.call("removeView", containment()->id());
0188         }
0189     });
0190     this->containment()->actions()->addAction(Latte::Data::ContextMenu::REMOVEVIEWACTION, m_actions[Latte::Data::ContextMenu::REMOVEVIEWACTION]);
0191 
0192     //! Signals
0193     connect(this->containment(), &Plasma::Containment::userConfiguringChanged, [=](){
0194         updateVisibleActions();
0195     });
0196 }
0197 
0198 void Menu::requestConfiguration()
0199 {
0200     if (this->containment()) {
0201         emit this->containment()->configureRequested(containment());
0202     }
0203 }
0204 
0205 void Menu::requestWidgetExplorer()
0206 {
0207     if (this->containment()) {
0208         emit this->containment()->showAddWidgetsInterface(QPointF());
0209     }
0210 }
0211 
0212 QList<QAction *> Menu::contextualActions()
0213 {
0214     QList<QAction *> actions;
0215 
0216     actions << m_actions[Latte::Data::ContextMenu::SECTIONACTION];
0217     actions << m_actions[Latte::Data::ContextMenu::PRINTACTION];
0218     for(int i=0; i<Latte::Data::ContextMenu::ACTIONSEDITORDER.count(); ++i) {
0219         actions << m_actions[Latte::Data::ContextMenu::ACTIONSEDITORDER[i]];
0220     }
0221     actions << m_actions[Latte::Data::ContextMenu::EDITVIEWACTION];
0222 
0223     m_data.clear();
0224     m_viewTemplates.clear();
0225     QDBusInterface iface("org.kde.lattedock", "/Latte", "", QDBusConnection::sessionBus());
0226 
0227     if (iface.isValid()) {
0228         QDBusReply<QStringList> contextData = iface.call("contextMenuData", containment()->id());
0229         m_data = contextData.value();
0230 
0231         QDBusReply<QStringList> templatesData = iface.call("viewTemplatesData");
0232         m_viewTemplates = templatesData.value();
0233     }
0234 
0235     m_actionsAlwaysShown = m_data[ACTIONSALWAYSSHOWN].split(";;");
0236 
0237     updateViewData();
0238 
0239     QString configureActionText = (m_view.type == DockView) ? i18n("&Edit Dock...") : i18n("&Edit Panel...");
0240     if (m_view.isCloned) {
0241         configureActionText = (m_view.type == DockView) ? i18n("&Edit Original Dock...") : i18n("&Edit Original Panel...");
0242     }
0243     m_actions[Latte::Data::ContextMenu::EDITVIEWACTION]->setText(configureActionText);
0244 
0245     const QString duplicateActionText = (m_view.type == DockView) ? i18n("&Duplicate Dock") : i18n("&Duplicate Panel");
0246     m_actions[Latte::Data::ContextMenu::DUPLICATEVIEWACTION]->setText(duplicateActionText);
0247 
0248     const QString exportTemplateText = (m_view.type == DockView) ? i18n("E&xport Dock as Template") : i18n("E&xport Panel as Template");
0249     m_actions[Latte::Data::ContextMenu::EXPORTVIEWTEMPLATEACTION]->setText(exportTemplateText);
0250 
0251     m_activeLayoutNames = m_data[ACTIVELAYOUTSINDEX].split(";;");
0252     const QString moveText = (m_view.type == DockView) ? i18n("&Move Dock To Layout") : i18n("&Move Panel To Layout");
0253     m_actions[Latte::Data::ContextMenu::MOVEVIEWACTION]->setText(moveText);
0254 
0255     const QString removeActionText = (m_view.type == DockView) ? i18n("&Remove Dock") : i18n("&Remove Panel");
0256     m_actions[Latte::Data::ContextMenu::REMOVEVIEWACTION]->setText(removeActionText);
0257 
0258     updateVisibleActions();
0259 
0260     return actions;
0261 }
0262 
0263 QAction *Menu::action(const QString &name)
0264 {
0265     if (m_actions.contains(name)) {
0266         return m_actions[name];
0267     }
0268 
0269     return nullptr;
0270 }
0271 
0272 void Menu::updateVisibleActions()
0273 {
0274     if (!m_actions.contains(Latte::Data::ContextMenu::EDITVIEWACTION)
0275             || !m_actions.contains(Latte::Data::ContextMenu::REMOVEVIEWACTION)) {
0276         return;
0277     }
0278 
0279     bool configuring = containment()->isUserConfiguring();
0280 
0281     // normal actions that the user can specify their visibility
0282     for(auto actionName: m_actions.keys()) {
0283         if (Latte::Data::ContextMenu::ACTIONSSPECIAL.contains(actionName)) {
0284             continue;
0285         } else if (Latte::Data::ContextMenu::ACTIONSALWAYSHIDDEN.contains(actionName)) {
0286             m_actions[actionName]->setVisible(false);
0287             continue;
0288         }
0289 
0290         bool isvisible = m_actionsAlwaysShown.contains(actionName) || configuring;
0291         m_actions[actionName]->setVisible(isvisible);
0292     }
0293 
0294     // normal actions with more criteria
0295     bool isshown = (m_actions[Latte::Data::ContextMenu::MOVEVIEWACTION]->isVisible() && m_activeLayoutNames.count()>1);
0296     m_actions[Latte::Data::ContextMenu::MOVEVIEWACTION]->setVisible(isshown);
0297 
0298     // special actions
0299     m_actions[Latte::Data::ContextMenu::EDITVIEWACTION]->setVisible(!configuring);
0300     m_actions[Latte::Data::ContextMenu::SECTIONACTION]->setVisible(true);
0301 
0302     if (m_view.isCloned) {
0303         m_actions[Latte::Data::ContextMenu::DUPLICATEVIEWACTION]->setVisible(false);
0304         m_actions[Latte::Data::ContextMenu::EXPORTVIEWTEMPLATEACTION]->setVisible(false);
0305         m_actions[Latte::Data::ContextMenu::MOVEVIEWACTION]->setVisible(false);
0306         m_actions[Latte::Data::ContextMenu::REMOVEVIEWACTION]->setVisible(false);
0307     }
0308 
0309     // because sometimes they are disabled unexpectedly, we should reenable them
0310     for(auto actionName: m_actions.keys()) {
0311         m_actions[actionName]->setEnabled(true);
0312     }
0313 }
0314 
0315 
0316 void Menu::populateLayouts()
0317 {
0318     m_switchLayoutsMenu->clear();
0319 
0320     LayoutsMemoryUsage memoryUsage = static_cast<LayoutsMemoryUsage>((m_data[MEMORYINDEX]).toInt());
0321     QStringList activeNames = m_data[ACTIVELAYOUTSINDEX].split(";;");
0322     QStringList currentNames = m_data[CURRENTLAYOUTSINDEX].split(";;");
0323 
0324     QList<LayoutInfo> layoutsmenulist;
0325 
0326     QStringList layoutsdata = m_data[LAYOUTMENUINDEX].split(";;");
0327 
0328     for (int i=0; i<layoutsdata.count(); ++i) {
0329         QStringList cdata = layoutsdata[i].split("**");
0330 
0331         LayoutInfo info;
0332         info.layoutName = cdata[0];
0333         info.isBackgroundFileIcon = cdata[1].toInt();
0334         info.iconName = cdata[2];
0335 
0336         layoutsmenulist << info;
0337     }
0338 
0339     for (int i = 0; i < layoutsmenulist.count(); ++i) {
0340         bool isActive = activeNames.contains(layoutsmenulist[i].layoutName);
0341 
0342         QString layoutText = layoutsmenulist[i].layoutName;
0343 
0344         bool isCurrent = ((memoryUsage == SingleLayout && isActive)
0345                           || (memoryUsage == MultipleLayouts && currentNames.contains(layoutsmenulist[i].layoutName)));
0346 
0347 
0348         QWidgetAction *action = new QWidgetAction(m_switchLayoutsMenu);
0349         action->setText(layoutsmenulist[i].layoutName);
0350         action->setCheckable(true);
0351         action->setChecked(isCurrent);
0352         action->setData(layoutsmenulist[i].layoutName);
0353 
0354         LayoutMenuItemWidget *menuitem = new LayoutMenuItemWidget(action, m_switchLayoutsMenu);
0355         menuitem->setIcon(layoutsmenulist[i].isBackgroundFileIcon, layoutsmenulist[i].iconName);
0356         action->setDefaultWidget(menuitem);
0357         m_switchLayoutsMenu->addAction(action);
0358     }
0359 
0360     m_switchLayoutsMenu->addSeparator();
0361 
0362     QWidgetAction *editaction = new QWidgetAction(m_switchLayoutsMenu);
0363     editaction->setText(i18n("Edit &Layouts..."));
0364     editaction->setCheckable(false);
0365     editaction->setData(QStringLiteral(" _show_latte_settings_dialog_"));
0366     editaction->setVisible(false);
0367 
0368     LayoutMenuItemWidget *editmenuitem = new LayoutMenuItemWidget(editaction, m_switchLayoutsMenu);
0369     editmenuitem->setIcon(false, "document-edit");
0370     editaction->setDefaultWidget(editmenuitem);
0371     m_switchLayoutsMenu->addAction(editaction);
0372 }
0373 
0374 void Menu::populateMoveToLayouts()
0375 {
0376     m_moveToLayoutMenu->clear();
0377 
0378     LayoutsMemoryUsage memoryUsage = static_cast<LayoutsMemoryUsage>((m_data[MEMORYINDEX]).toInt());
0379 
0380     if (memoryUsage == LayoutsMemoryUsage::MultipleLayouts) {
0381         QStringList activeNames = m_data[ACTIVELAYOUTSINDEX].split(";;");
0382         QStringList currentNames = m_data[CURRENTLAYOUTSINDEX].split(";;");
0383         QString viewLayoutName = m_data[VIEWLAYOUTINDEX];
0384 
0385         QList<LayoutInfo> layoutsmenulist;
0386 
0387         QStringList layoutsdata = m_data[LAYOUTMENUINDEX].split(";;");
0388 
0389         for (int i=0; i<layoutsdata.count(); ++i) {
0390             QStringList cdata = layoutsdata[i].split("**");
0391 
0392             LayoutInfo info;
0393             info.layoutName = cdata[0];
0394             info.isBackgroundFileIcon = cdata[1].toInt();
0395             info.iconName = cdata[2];
0396 
0397             layoutsmenulist << info;
0398         }
0399 
0400         for (int i = 0; i < layoutsmenulist.count(); ++i) {
0401             bool isCurrent = currentNames.contains(layoutsmenulist[i].layoutName) && activeNames.contains(layoutsmenulist[i].layoutName);
0402             bool isViewCurrentLayout = layoutsmenulist[i].layoutName == viewLayoutName;
0403 
0404             QWidgetAction *action = new QWidgetAction(m_moveToLayoutMenu);
0405             action->setText(layoutsmenulist[i].layoutName);
0406             action->setCheckable(true);
0407             action->setChecked(isViewCurrentLayout);
0408             action->setData(isViewCurrentLayout ? QString() : layoutsmenulist[i].layoutName);
0409 
0410             LayoutMenuItemWidget *menuitem = new LayoutMenuItemWidget(action, m_moveToLayoutMenu);
0411             menuitem->setIcon(layoutsmenulist[i].isBackgroundFileIcon, layoutsmenulist[i].iconName);
0412             action->setDefaultWidget(menuitem);
0413             m_moveToLayoutMenu->addAction(action);
0414         }
0415     }
0416 }
0417 
0418 void Menu::updateViewData()
0419 {
0420     QStringList vdata = m_data[VIEWTYPEINDEX].split(";;");
0421     m_view.type = static_cast<ViewType>((vdata[0]).toInt());
0422     m_view.isCloned = vdata[1].toInt();
0423     m_view.clonesCount = vdata[2].toInt();
0424 }
0425 
0426 void Menu::populateViewTemplates()
0427 {
0428     m_addViewMenu->clear();
0429 
0430     for(int i=0; i<m_viewTemplates.count(); ++i) {
0431         if (i % 2 == 1) {
0432             //! even records are the templates ids and they have already been registered
0433             continue;
0434         }
0435 
0436         QAction *templateAction = m_addViewMenu->addAction(m_viewTemplates[i]);
0437         templateAction->setIcon(QIcon::fromTheme("list-add"));
0438         templateAction->setData(m_viewTemplates[i+1]);
0439     }
0440 
0441     QAction *templatesSeparatorAction = m_addViewMenu->addSeparator();
0442     QAction *duplicateAction = m_addViewMenu->addAction(m_actions[Latte::Data::ContextMenu::DUPLICATEVIEWACTION]->text());
0443     duplicateAction->setToolTip(m_actions[Latte::Data::ContextMenu::DUPLICATEVIEWACTION]->toolTip());
0444     duplicateAction->setIcon(m_actions[Latte::Data::ContextMenu::DUPLICATEVIEWACTION]->icon());
0445     connect(duplicateAction, &QAction::triggered, m_actions[Latte::Data::ContextMenu::DUPLICATEVIEWACTION], &QAction::triggered);
0446 }
0447 
0448 void Menu::addView(QAction *action)
0449 {
0450     const QString templateId = action->data().toString();
0451 
0452     QTimer::singleShot(400, [this, templateId]() {
0453         QDBusInterface iface("org.kde.lattedock", "/Latte", "", QDBusConnection::sessionBus());
0454 
0455         if (iface.isValid()) {
0456             iface.call("addView", containment()->id(), templateId);
0457         }
0458     });
0459 }
0460 
0461 void Menu::moveToLayout(QAction *action)
0462 {
0463     const QString layoutName = action->data().toString();
0464 
0465     QTimer::singleShot(400, [this, layoutName]() {
0466         QDBusInterface iface("org.kde.lattedock", "/Latte", "", QDBusConnection::sessionBus());
0467 
0468         if (iface.isValid()) {
0469             iface.call("moveViewToLayout", containment()->id(), layoutName);
0470         }
0471     });
0472 }
0473 
0474 void Menu::switchToLayout(QAction *action)
0475 {
0476     const QString layout = action->data().toString();
0477 
0478     if (layout == QLatin1String(" _show_latte_settings_dialog_")) {
0479         QTimer::singleShot(400, [this]() {
0480             QDBusInterface iface("org.kde.lattedock", "/Latte", "", QDBusConnection::sessionBus());
0481 
0482             if (iface.isValid()) {
0483                 iface.call("showSettingsWindow", (int)LayoutPage);
0484             }
0485         });
0486     } else {
0487         QTimer::singleShot(400, [this, layout]() {
0488             QDBusInterface iface("org.kde.lattedock", "/Latte", "", QDBusConnection::sessionBus());
0489 
0490             if (iface.isValid()) {
0491                 iface.call("switchToLayout", layout);
0492             }
0493         });
0494     }
0495 }
0496 
0497 void Menu::quitApplication()
0498 {
0499     QDBusInterface iface("org.kde.lattedock", "/Latte", "", QDBusConnection::sessionBus());
0500 
0501     if (iface.isValid()) {
0502         iface.call("quitApplication");
0503     }
0504 }
0505 
0506 K_PLUGIN_CLASS_WITH_JSON(Menu, "plasma-containmentactions-lattecontextmenu.json")
0507 
0508 #include "menu.moc"