File indexing completed on 2025-05-04 04:51:07

0001 /*
0002    SPDX-FileCopyrightText: 2016-2024 Laurent Montel <montel@kde.org>
0003 
0004    SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 #include "viewerpluginexternalscriptinterface.h"
0007 #include "externalscriptplugin_debug.h"
0008 #include "viewerpluginexternalscriptmanager.h"
0009 #include "viewerpluginexternalscriptparseargument.h"
0010 
0011 #include <QAction>
0012 #include <QActionGroup>
0013 #include <QIcon>
0014 #include <QPointer>
0015 #include <QProcess>
0016 #include <QStandardPaths>
0017 
0018 #include <KActionCollection>
0019 #include <KLocalizedString>
0020 #include <KMessageBox>
0021 #include <QMenu>
0022 
0023 #include "configuredialog/viewerpluginexternalconfiguredialog.h"
0024 
0025 using namespace MessageViewer;
0026 
0027 ViewerPluginExternalscriptInterface::ViewerPluginExternalscriptInterface(KActionCollection *ac, QWidget *parent)
0028     : ViewerPluginInterface(parent)
0029     , mActionGroup(new QActionGroup(this))
0030 {
0031     createAction(ac);
0032 }
0033 
0034 ViewerPluginExternalscriptInterface::~ViewerPluginExternalscriptInterface() = default;
0035 
0036 void ViewerPluginExternalscriptInterface::refreshActionList(KActionCollection *ac)
0037 {
0038     ViewerPluginExternalScriptManager::self()->readExternalScriptInfo();
0039     delete mActionGroup;
0040     for (QAction *act : std::as_const(mAction)) {
0041         ac->removeAction(act);
0042     }
0043     mAction.clear();
0044     mActionGroup = new QActionGroup(this);
0045     createAction(ac);
0046 }
0047 
0048 void ViewerPluginExternalscriptInterface::setMessageItem(const Akonadi::Item &item)
0049 {
0050     mAkonadiUrl = item.url(Akonadi::Item::UrlWithMimeType).toString();
0051 }
0052 
0053 void ViewerPluginExternalscriptInterface::setMessage(const KMime::Message::Ptr &msg)
0054 {
0055     mMessage = msg;
0056 }
0057 
0058 QList<QAction *> ViewerPluginExternalscriptInterface::actions() const
0059 {
0060     return mAction;
0061 }
0062 
0063 ViewerPluginInterface::SpecificFeatureTypes ViewerPluginExternalscriptInterface::featureTypes() const
0064 {
0065     return NeedMessage;
0066 }
0067 
0068 void ViewerPluginExternalscriptInterface::setText(const QString &text)
0069 {
0070     mText = text;
0071 }
0072 
0073 void ViewerPluginExternalscriptInterface::execute()
0074 {
0075     if (mCurrentInfo.count() == 2) {
0076         const QString executable = mCurrentInfo.at(1);
0077         const QString executablePath = QStandardPaths::findExecutable(executable);
0078         if (executablePath.isEmpty()) {
0079             KMessageBox::error(nullptr, i18n("\'%1\' not found", executable), i18nc("@title:window", "Executable not found."));
0080         } else {
0081             QProcess proc;
0082             const QStringList newCommandLine = mCurrentInfo.at(0).split(QLatin1Char(' '), Qt::SkipEmptyParts);
0083             const QStringList splitArguments = adaptArguments(newCommandLine);
0084             if (!proc.startDetached(executablePath, splitArguments)) {
0085                 KMessageBox::error(nullptr, i18n("Impossible to start executable"));
0086             }
0087         }
0088     } else {
0089         qCDebug(EXTERNALSCRIPTPLUGIN_LOG) << "Problem with number of arguments " << mCurrentInfo.count();
0090     }
0091     clear();
0092 }
0093 
0094 void ViewerPluginExternalscriptInterface::clear()
0095 {
0096     mText.clear();
0097     mCurrentInfo.clear();
0098     mMessage.clear();
0099 }
0100 
0101 void ViewerPluginExternalscriptInterface::createAction(KActionCollection *ac)
0102 {
0103     if (ac) {
0104         auto mainMenu = new QAction(i18n("External Script"), this);
0105         const QList<ViewerPluginExternalScriptInfo> infos = ViewerPluginExternalScriptManager::self()->scriptInfos();
0106         auto menu = new QMenu;
0107         if (!infos.isEmpty()) {
0108             connect(mActionGroup, &QActionGroup::triggered, this, &ViewerPluginExternalscriptInterface::slotScriptActivated);
0109             for (const ViewerPluginExternalScriptInfo &info : infos) {
0110                 auto act = new QAction(info.name(), menu);
0111                 act->setIconText(info.name());
0112                 const QString &description = info.description();
0113                 if (!description.isEmpty()) {
0114                     addHelpTextAction(act, description);
0115                 }
0116                 const QString &icon = info.icon();
0117                 if (!icon.isEmpty()) {
0118                     act->setIcon(QIcon::fromTheme(icon));
0119                 }
0120                 ac->addAction(QStringLiteral("externalscript_%1").arg(info.name()), act);
0121                 const QStringList actionInfo{info.commandLine(), info.executable()};
0122 
0123                 act->setData(actionInfo);
0124                 menu->addAction(act);
0125                 mActionGroup->addAction(act);
0126             }
0127             menu->addSeparator();
0128         }
0129         auto act = new QAction(QIcon::fromTheme(QStringLiteral("settings-configure")), i18n("Configure"), menu);
0130         connect(act, &QAction::triggered, this, &ViewerPluginExternalscriptInterface::slotConfigure);
0131         menu->addAction(act);
0132         mainMenu->setMenu(menu);
0133         act = new QAction(menu);
0134         act->setSeparator(true);
0135         mAction << mainMenu << act;
0136     }
0137 }
0138 
0139 void ViewerPluginExternalscriptInterface::slotConfigure()
0140 {
0141     QPointer<ViewerPluginExternalConfigureDialog> dlg = new ViewerPluginExternalConfigureDialog;
0142     if (dlg->exec()) {
0143         Q_EMIT configChanged();
0144     }
0145     delete dlg;
0146 }
0147 
0148 void ViewerPluginExternalscriptInterface::slotScriptActivated(QAction *act)
0149 {
0150     mCurrentInfo = act->data().toStringList();
0151     slotActivatePlugin();
0152 }
0153 
0154 QStringList ViewerPluginExternalscriptInterface::adaptArguments(const QStringList &scriptArguments)
0155 {
0156     ViewerPluginExternalScriptParseArgument parser;
0157     parser.setMessage(mMessage);
0158     parser.setAkonadiUrl(mAkonadiUrl);
0159     return parser.parse(scriptArguments);
0160 }
0161 
0162 #include "moc_viewerpluginexternalscriptinterface.cpp"