Warning, file /plasma/plasma-workspace/shell/currentcontainmentactionsmodel.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 /*
0002     SPDX-FileCopyrightText: 2013 Marco Martin <mart@kde.org>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #include "currentcontainmentactionsmodel.h"
0008 
0009 #include <QMouseEvent>
0010 
0011 #include <QDebug>
0012 #include <QDialog>
0013 #include <QDialogButtonBox>
0014 #include <QQuickItem>
0015 #include <QQuickWindow>
0016 #include <QVBoxLayout>
0017 #include <QWindow>
0018 
0019 #include <klocalizedstring.h>
0020 
0021 #include <Plasma/Containment>
0022 #include <Plasma/ContainmentActions>
0023 #include <Plasma/Corona>
0024 #include <Plasma/PluginLoader>
0025 
0026 using namespace Qt::StringLiterals;
0027 
0028 CurrentContainmentActionsModel::CurrentContainmentActionsModel(Plasma::Containment *containment, QObject *parent)
0029     : QStandardItemModel(parent)
0030     , m_containment(containment)
0031     , m_tempConfigParent(QString(), KConfig::SimpleConfig)
0032 {
0033     m_baseCfg = KConfigGroup(m_containment->corona()->config(), u"ActionPlugins"_s);
0034     m_baseCfg = KConfigGroup(&m_baseCfg, QString::number((int)m_containment->containmentType()));
0035 
0036     QHash<QString, Plasma::ContainmentActions *> actions = containment->containmentActions();
0037 
0038     QHashIterator<QString, Plasma::ContainmentActions *> i(actions);
0039     while (i.hasNext()) {
0040         i.next();
0041 
0042         QStandardItem *item = new QStandardItem();
0043         item->setData(i.key(), ActionRole);
0044         item->setData(i.value()->metadata().pluginId(), PluginNameRole);
0045 
0046         m_plugins[i.key()] = Plasma::PluginLoader::self()->loadContainmentActions(m_containment, i.value()->metadata().pluginId());
0047         m_plugins[i.key()]->setContainment(m_containment);
0048         KConfigGroup cfg(&m_baseCfg, i.key());
0049         m_plugins[i.key()]->restore(cfg);
0050         item->setData(m_plugins[i.key()]->metadata().rawData().value(QStringLiteral("X-Plasma-HasConfigurationInterface")).toBool(),
0051                       HasConfigurationInterfaceRole);
0052 
0053         appendRow(item);
0054     }
0055 }
0056 
0057 CurrentContainmentActionsModel::~CurrentContainmentActionsModel()
0058 {
0059 }
0060 
0061 QHash<int, QByteArray> CurrentContainmentActionsModel::roleNames() const
0062 {
0063     return {
0064         {ActionRole, "action"},
0065         {PluginNameRole, "pluginName"},
0066         {HasConfigurationInterfaceRole, "hasConfigurationInterface"},
0067     };
0068 }
0069 
0070 QString CurrentContainmentActionsModel::mouseEventString(int mouseButton, int modifiers)
0071 {
0072     QMouseEvent *mouse =
0073         new QMouseEvent(QEvent::MouseButtonRelease, QPoint(), (Qt::MouseButton)mouseButton, (Qt::MouseButton)mouseButton, (Qt::KeyboardModifiers)modifiers);
0074 
0075     const QString string = Plasma::ContainmentActions::eventToString(mouse);
0076 
0077     delete mouse;
0078 
0079     return string;
0080 }
0081 
0082 QString CurrentContainmentActionsModel::wheelEventString(QObject *quickWheelEvent)
0083 {
0084     const QPoint angleDelta = quickWheelEvent->property("angleDelta").toPoint();
0085     const auto buttons = Qt::MouseButtons(quickWheelEvent->property("buttons").toInt());
0086     const auto modifiers = Qt::KeyboardModifiers(quickWheelEvent->property("modifiers").toInt());
0087 
0088     QWheelEvent wheel(QPointF(), QPointF(), QPoint(), angleDelta, buttons, modifiers, Qt::NoScrollPhase, false);
0089 
0090     return Plasma::ContainmentActions::eventToString(&wheel);
0091 }
0092 
0093 bool CurrentContainmentActionsModel::isTriggerUsed(const QString &trigger)
0094 {
0095     return m_plugins.contains(trigger);
0096 }
0097 
0098 bool CurrentContainmentActionsModel::append(const QString &action, const QString &plugin)
0099 {
0100     if (m_plugins.contains(action)) {
0101         return false;
0102     }
0103 
0104     QStandardItem *item = new QStandardItem();
0105     item->setData(action, ActionRole);
0106     item->setData(plugin, PluginNameRole);
0107 
0108     Plasma::ContainmentActions *actions = Plasma::PluginLoader::self()->loadContainmentActions(m_containment, plugin);
0109 
0110     if (!actions) {
0111         return false;
0112     }
0113 
0114     m_plugins[action] = actions;
0115     m_plugins[action]->setContainment(m_containment);
0116     // empty config: the new one will ne in default state
0117     KConfigGroup tempConfig(&m_tempConfigParent, u"test"_s);
0118     m_plugins[action]->restore(tempConfig);
0119     item->setData(m_plugins[action]->metadata().rawData().value(QStringLiteral("X-Plasma-HasConfigurationInterface")).toBool(), HasConfigurationInterfaceRole);
0120     m_removedTriggers.removeAll(action);
0121 
0122     appendRow(item);
0123 
0124     Q_EMIT configurationChanged();
0125     return true;
0126 }
0127 
0128 void CurrentContainmentActionsModel::update(int row, const QString &action, const QString &plugin)
0129 {
0130     const QString oldPlugin = itemData(index(row, 0)).value(PluginNameRole).toString();
0131     const QString oldTrigger = itemData(index(row, 0)).value(ActionRole).toString();
0132 
0133     if (oldTrigger == action && oldPlugin == plugin) {
0134         return;
0135     }
0136 
0137     QModelIndex idx = index(row, 0);
0138 
0139     if (idx.isValid()) {
0140         setData(idx, action, ActionRole);
0141         setData(idx, plugin, PluginNameRole);
0142 
0143         delete m_plugins[oldTrigger];
0144         m_plugins.remove(oldTrigger);
0145 
0146         if (oldPlugin != plugin) {
0147             m_removedTriggers << oldTrigger;
0148         }
0149 
0150         if (!m_plugins.contains(action) || oldPlugin != plugin) {
0151             delete m_plugins[action];
0152             m_plugins[action] = Plasma::PluginLoader::self()->loadContainmentActions(m_containment, plugin);
0153             m_plugins[action]->setContainment(m_containment);
0154             // empty config: the new one will ne in default state
0155             KConfigGroup tempConfig(&m_tempConfigParent, u"test"_s);
0156             m_plugins[action]->restore(tempConfig);
0157             setData(idx,
0158                     m_plugins[action]->metadata().rawData().value(QStringLiteral("X-Plasma-HasConfigurationInterface")).toBool(),
0159                     HasConfigurationInterfaceRole);
0160         }
0161 
0162         Q_EMIT configurationChanged();
0163     }
0164 }
0165 
0166 void CurrentContainmentActionsModel::remove(int row)
0167 {
0168     const QString action = itemData(index(row, 0)).value(ActionRole).toString();
0169     removeRows(row, 1);
0170 
0171     if (m_plugins.contains(action)) {
0172         delete m_plugins[action];
0173         m_plugins.remove(action);
0174         m_removedTriggers << action;
0175         Q_EMIT configurationChanged();
0176     }
0177 }
0178 
0179 void CurrentContainmentActionsModel::showConfiguration(int row, QQuickItem *ctx)
0180 {
0181     const QString action = itemData(index(row, 0)).value(ActionRole).toString();
0182 
0183     if (!m_plugins.contains(action)) {
0184         return;
0185     }
0186 
0187     QDialog *configDlg = new QDialog();
0188     configDlg->setAttribute(Qt::WA_DeleteOnClose);
0189     QLayout *lay = new QVBoxLayout(configDlg);
0190     configDlg->setLayout(lay);
0191     if (ctx && ctx->window()) {
0192         configDlg->setWindowModality(Qt::WindowModal);
0193         configDlg->winId(); // so it creates the windowHandle();
0194         configDlg->windowHandle()->setTransientParent(ctx->window());
0195     }
0196 
0197     Plasma::ContainmentActions *pluginInstance = m_plugins[action];
0198     // put the config in the dialog
0199     QWidget *w = pluginInstance->createConfigurationInterface(configDlg);
0200     QString title;
0201     if (w) {
0202         lay->addWidget(w);
0203         title = w->windowTitle();
0204     }
0205 
0206     configDlg->setWindowTitle(title.isEmpty() ? i18n("Configure Mouse Actions Plugin") : title);
0207     // put buttons below
0208     QDialogButtonBox *buttons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal, configDlg);
0209     lay->addWidget(buttons);
0210 
0211     connect(buttons, &QDialogButtonBox::accepted, configDlg, &QDialog::accept);
0212     connect(buttons, &QDialogButtonBox::rejected, configDlg, &QDialog::reject);
0213 
0214     QObject::connect(configDlg, &QDialog::accepted, pluginInstance, [pluginInstance]() {
0215         pluginInstance->configurationAccepted();
0216     });
0217 
0218     connect(configDlg, &QDialog::accepted, this, &CurrentContainmentActionsModel::configurationChanged);
0219 
0220     connect(pluginInstance, &QObject::destroyed, configDlg, &QDialog::reject);
0221 
0222     configDlg->show();
0223 }
0224 
0225 QVariant CurrentContainmentActionsModel::aboutMetaData(int row) const
0226 {
0227     const QString action = itemData(index(row, 0)).value(ActionRole).toString();
0228 
0229     if (!m_plugins.contains(action)) {
0230         return QVariant();
0231     }
0232 
0233     return QVariant::fromValue(m_plugins[action]->metadata());
0234 }
0235 
0236 void CurrentContainmentActionsModel::save()
0237 {
0238     foreach (const QString &removedTrigger, m_removedTriggers) {
0239         m_containment->setContainmentActions(removedTrigger, QString());
0240     }
0241     m_removedTriggers.clear();
0242 
0243     QHashIterator<QString, Plasma::ContainmentActions *> i(m_plugins);
0244     while (i.hasNext()) {
0245         i.next();
0246 
0247         KConfigGroup cfg(&m_baseCfg, i.key());
0248         i.value()->save(cfg);
0249 
0250         m_containment->setContainmentActions(i.key(), i.value()->metadata().pluginId());
0251     }
0252 }
0253 
0254 #include "moc_currentcontainmentactionsmodel.cpp"